我有一个这样定义的对象:
public class QuestionSetAssignee
{
[Required]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public virtual ICollection<QuestionSet> QuestionSets { get; set; }
public override int GetHashCode()
{
return Id.GetHashCode();
}
public override bool Equals(Object obj)
{
if (obj == null)
{
return false;
}
QuestionSetAssignee qsa = obj as QuestionSetAssignee;
return Id == qsa.Id;
}
}
下面的语句:
QuestionSetAssignees.Contains(director)
在
public bool isEditable()
{
ApplicationDbContext db = new ApplicationDbContext();
QuestionSetAssignee director = db.QuestionSetAssignees.Find((int)QuestionSetAssigneeEnum.Director);
if (Conference.AcceptingDirectorApplications && QuestionSetAssignees.Contains(director))
{
return false;
}
return true;
}
返回 false,据我所知应该返回 true。 (注:Conference.AcceptingDirectorApplications返回true)
如果不是很清楚,director 对象和 HashSet 对象作为 DynamicProxies 出现(由于 EF 和对象层次结构)。
这是导演对象:
这是 QuestionSetAssignees 对象:
我无法控制 QuestionSetAsignees 的类型,因为它由 EF 6 提供(它在模型中声明为 ICollection。这也意味着我无法提供比较对象(好吧,据我所知)。我想要做的就是能够比较两个 QuestionSetAsignee 对象。我也尝试过实现 IEquatable,但那没有用。
最佳答案
问题是它将您的 Contains()
转换为 SQL 调用,因此无论您在 Equals
和 GetHashCode()
中放入什么> 这无关紧要,因为您连接的数据库不使用它们来测试相等性(这就是为什么 "This"== "this"
将返回 true
的原因在整理不区分大小写的数据库上使用 Entity Framework )。
修复它的“快速而肮脏”的方法是在内存中实现集合,然后执行 .Contains
QuestionSetAssignees.AsEnumerable().Contains(director))
但这不会给你很好的表现。您可能需要以不同的方式处理此查询,以便 SQL 的行为符合您的要求。
我认为以下可能有效,但请测试一下,如果无效请告诉我,我会删除它。
QuestionSetAssignees.Select(assignee => assignee.Id).Contains(director.Id)
关于c# - ICollection<>.Contains 在 EF 中,因为 HashSet 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21769901/