使用Linq在两个列表之间规范化的最佳方法是什么?

时间:2013-11-20 22:17:12

标签: c# linq entity-framework-5

在C#中给出两个IEnumerable实例(称之为a和b),删除不在b中的所有值的最佳方法是什么,并添加不在b中的所有b值?

我知道我通常可以设置a = b,但这最终是为了通过实体框架CodeFirst在MVC应用程序中持久保存到DB,因此需要注意一些状态。事实上,我们正在谈论根据客户发布的内容更新记录。

似乎工作的最接近的涉及foreach循环,一个迭代'a'列表并填充'要删除的项'的集合,另一个迭代'b'列表以识别'项目是添加',然后分别在'要删除的项'和'要添加的项'集合中分别添加和删除项目(因为您在迭代时无法修改'a'集合。

但是,这感觉很笨重;有更好的方法吗?

更新 为清楚起见,我会举个例子。假设我有一个我从DB中获取的实体代表一个博客帖子(因为那个例子永远不会累...)并且说Post有一组标签。从客户端,我得到一个标签列表,现在应该是标准的“规范”列表,但它们都不是实体,它只是一个内存中的集合。我想要做的是确保Post.Tags匹配客户端发布的标签,而不在数据库中创建重复的标签。

2 个答案:

答案 0 :(得分:5)

您可以使用IntersectConcatExcept

a = a.Intersect(b).Concat(b.Except(a));

Intersect会返回两个集合中都存在的项目,因此a.Intersect(b)会为您提供ab中的所有项目。

Except会返回第一个集合中的元素,但不会返回另一个集合中的元素,因此b.Except(a)会返回b但不在a中的元素。

Concat连接这两个集合。

但我不能真正回答你的问题,因此我不确定这是你在寻找什么。

答案 1 :(得分:0)

听起来您的可枚举a实际上是一个列表,所以我这样做了:

var a = new List<int>() { 1, 2, 3, };
var b = new List<int>() { 1, 3, 4, 5, };

foreach (var x in a.Except(b).ToArray())
{
    a.Remove(x);
}

foreach (var x in b.Except(a).ToArray())
{
    a.Add(x);
}

最后ab具有相同的元素。

但是,如果b中有重复项,则需要小心。