2016-06-17 81 views
1

因此,我最终将自己的头围绕自我引用EF代码中的多对多关系首先我想,但现在我可以进入关于最佳方式更新这些关系。EF代码优先自引用多对多更新引用

比方说,我们有这样的关系:

modelBuilder.Entity<Contact>() 
        .HasMany(c => c.Friends) 
        .WithMany() 

与在Contact.cs类以下内容:

public virtual iCollection<Contact> Friends {get;set;}; 

在我的联系人视图,我有一个多选,选择朋友的联系。然后通过遍历所有选中的部分并运行thisContact.Friends.Add(friend)并保存更改来保存。

然后,当您回到联系人视图时,很容易找回.Friends并重新填充多选,但我一直遇到重新保存新朋友的问题。什么是最好的方式去做呢?我首先想到删除所有的朋友,然后从多选中添加新的,但这似乎不是很有效,我不确定删除.Friends与保存Contact有什么关系。

是否有一种干净的方式来通过从multiselect中选择的新项目,将其与thisContact.Friends中已有的项目进行比较,添加新项目,删除那些不存在并保留匹配的项目?

我希望这是有道理的,谢谢你提前!

+0

只是取代朋友是迄今为止最简单的方法。这并不昂贵,因为只涉及非常小的记录(除非有数百个项目)。 –

+0

你的意思是删除存在的朋友,然后添加新的朋友? – blubberbo

+0

是的。只有联结表中的记录被删除并重新插入,而不是联系人本身。 –

回答

1

假设你有你的域名收集(contact.Friends)和你的朋友收集从UI(uiFriends)返回。

首先你会发现已经被删除的好友(伪代码)

var removeTheseFriends = contact.Friends.Except(uiFriends); // Returns friends that are only in your domain collection 
var addTheseFriends = uiFriends.Except(contact.Friends); // Returns friends only in your UI collection 

的“除”的方法是唯一的好,如果你正在传递完整的对象。 https://msdn.microsoft.com/en-us/library/bb300779(v=vs.90).aspx

实际上,UI集合可能是Friends集合中联系人的ID列表。在这种情况下,你可以这样做:

var removeTheseFriends = contact.Friends.Where(i => !uiFriends.Contains(i.Id)); 

// First load the list of friends that correspond to your ui collection Ids 
var domainObjectsOfUiFriendsCollection = context.Contacts.Where(i => uiFriends.Contains(i.Id)); 

// These are now domain objects, so you can now use the Except functionality 
var addTheseFriends = domainObjectsOfUiFriendsCollection.Except(contact.Friends); 

然后只是遍历列表并根据需要添加/删除它们。

+0

感谢您的信息!我想我会留在删除,然后再次添加它们,因为我不认为这会对系统造成太大的税收 – blubberbo

+0

有了上述内容,只需删除那些需要删除的内容并添加新内容即可。不改变的联系人不需要做任何事情。 – user1455010

+0

我很抱歉,但我不确定你的最后一句话是什么“然后只是遍历你的列表并根据需要添加/删除它们。”会看你创建的变量。你介意给我写信吗? – blubberbo