我有以下代码段。
// Here I get an entity out of an EntityCollection<TEntity> i.e ContactSet. Entity is obtained and not null.
ProjectContact obj = ((Project)projectDataGrid.SelectedItem).ContactSet
.Where(projectContact => projectContact.ProjectId == item.ProjectId &&
projectContact.ContactId == item.ContactId).First();
// And the next line I just check whether ContactSet contains the queried entity that i.e. obj.
bool found = ((Project)projectDataGrid.SelectedItem).ContactSet.Contains(obj);
但发现总是错误的。怎么会这样?
编辑:Matt感谢您的指导,但由于我没有提供完整的源代码,所以让我更清楚一点。
我的数据库中有三个表:
项目,联系人和ProjectContact并且通过ProjectContact表在Project和Contact表之间存在多对多关系,尽管ProjectContact表除了Project和Contact表键之外还有一些额外的列,这就是为什么我得到一个额外的实体如果我使用ADO.NET实体框架的实体设计器生成代码,则称为ProjectContact。
现在,在某些时候,我通过使用linq to entities查询在我的代码中获得了一个Project实例,即:
var item = (from project in myObjectContext.Project.Include("ContactSet.Contact")
orderby project.Name select project).FirstOrDefault();
请注意,ContactSet是Project to ProjectContact表的导航属性,Contact是ProjectContact到Contact表的导航属性。
此外,查询的项目即“item”在其item.ContactSet实体集合中已经有一些ProjectContacts,而ContactSet是由实体设计者生成的标准EntityCollection实现。
另一方面,ProjectContact会覆盖Equals()和GetHashCode()等。但是如果我在EqualityComparer中使用那个overriden实现,那么Project.ContactSet.Contains返回true,所以我猜这没有问题,但现在棘手的部分出现了。假设我有以下代码段:
using(SomeObjectContext myObjectContext = new SomeObjectContext())
{
var projectQueryable = from project in myObjectContext.Project.Include("ContactSet.Contact") orderby project.Name select project;
ObservableCollection<Project> projects = new ObservableCollection<Project>(projectQueryable.ToList());
var contactQueryable = from contact in myObjectContext.Contact select contact;
ObservableCollection<Contact> contacts = new ObservableCollection<Contact>(contactQueryable.ToList());
Project p = projects[0];
Contact c = contacts[0];
//Now if I execute the code below it fails.
ProjectContact projectContact = new ProjectContact();
projectContact.Contact = c;
projectContact.Project = p;
projectContact.ContactId = c.Id;
projectContact.ProjectId = p.Id;
projectContact.Role = ContactRole.Administrator; // This corresponds to the column in ProjectContact table and I do manual conversion within the partial class since EF doesn't support enums yet.
p.ContactSet.Add(projectContact); // This line might be unnecessary but just to be on the safe side.
// So now p.ContactSet does indeed contain the projectContact and projectContact's EntityState is Added as expected. But when I execute the line below without saving changes it fails.
bool result = p.ContactSet.Remove(projectContact); // result == false and projectContact is still in the p.ContactSet EntityCollection.
//Now if I execute the line below
myObjectContext.Delete(projectContact);
//Now projectContact's EntityState becomes Detached but it's still in p.ContactSet.
// Also note that if I test
bool exists = p.ContactSet.Contains(projectContact);
// It also returns false even if I query the item with p.ProjectContact.Where(...) it returns false.
}
由于所有内容都发生在同一个ObjectContext中,我想我错过了一些关于EntityCollection.Remove()的内容。但似乎仍然奇怪的是,ContactSet.Contains()为通过Contact Contact查询获得的项返回false。最后问题变成了:
如何在不首先持久保存到数据库的情况下从EntityCollection中删除项目。由于Add()之后的Remove()调用显然失败了。
答案 0 :(得分:0)
这看起来应该有用,有些想法:
ProjectContact是否覆盖Object.Equals()?或者也许ContactSet实现了ICollection,ICollection.Contains()的实现可能存在错误?