我与EF中的连接表有很多关系。
我在其他问题中似乎有一些建议,要求Hashset
集合类型用于多对多关系并覆盖Equals()和GetHashCode()。
我为什么要使用Hashset?
如何覆盖这些方法以及这取得了什么成果?
public class ChartQuery
{
public int ChartQueryId { get; set; }
public virtual ICollection<UserChartQuery> Users { get; set; }
...more...
}
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<UserChartQuery> SavedChartQueries { get; set; }
...more...
}
public class UserChartQuery
{
public int UserId { get; set; }
public int ChartQueryId { get; set; }
public virtual User User { get; set; }
public virtual ChartQuery ChartQuery { get; set; }
}
答案 0 :(得分:1)
我为什么要使用Hashset?
你不应该。只要映射正确,就会在数据库级别强制执行多对多行的唯一性。在应用程序级别执行它几乎没有任何好处。
如何覆盖这些方法以及这取得了什么成果?
实体框架中的多对多关系没有用于表示关系的独特实体,因此没有实体可以覆盖Equals()
和GetHashCode()
。
你可以定义一个实体以满足多对多关系,但从对象模型的角度来看,这有点人为和丑陋。如果你这样做,你将覆盖Equals()
和GetHashCode()
,并将相等性定义为参与的密钥彼此相等,并且哈希码将是参与密钥的唯一组合。 / p>
<强>更新强>
将您的示例与代表多对多关系的实体一起使用,这就是您实现Equals
和GetHashCode
的方式,以便它可以在HashSet中正确使用:
public class UserChartQuery
{
public int UserId { get; set; }
public int ChartQueryId { get; set; }
public virtual User User { get; set; }
public virtual ChartQuery ChartQuery { get; set; }
protected bool Equals(UserChartQuery other)
{
return UserId == other.UserId && ChartQueryId == other.ChartQueryId;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != this.GetType()) return false;
return Equals((UserChartQuery) obj);
}
public override int GetHashCode()
{
unchecked
{
return (UserId*397) ^ ChartQueryId;
}
}
}
如上所述,我建议使用更自然和内置的方式在EF中建立多对多关系:
public class ChartQuery
{
public int ChartQueryId { get; set; }
public virtual ICollection<User> Users { get; set; }
...more...
}
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<ChartQuery> SavedChartQueries { get; set; }
...more...
}
在映射中,您将定义多对多关系(在DbContext OnModelCreating覆盖中):
builder.Entity<ChartQuery>()
.HasMany(cq => ucq.Users)
.WithMany(u => u.SavedChartQueries);
在任何一种情况下,我都认为使用HashSet是不必要的。即使实体满足多对多关系,数据库也会强制复合密钥的唯一性。