C#从具有多个属性的两个列表中删除重复项

时间:2014-08-20 09:23:49

标签: c# linq merge union

我想将随机元素插入现有数据库。在插入这些随机元素之前,我必须检查它们是否已存在于数据库中(主键)。我想要添加额外的ID属性。

因此我想获得重复但只有重复的主键,因此.Union()不起作用。

以下是两个解决方案:

var databaseList = database.Repository.GetAllElements();
foreach (var element in listOfRandomElements.Where(element => databaseList.Find(
                x =>
                x.Property0 == element.Property0 &&
                x.Property1 == element.Property1 &&
                x.Property2 == element.Property2)
                != null))
 {
     listOfElements.Remove(element);
 }


 listOfElements.RemoveAll(x => x.Property0 == databaseList.Select(y => true).Property0);

第一个解决方案不起作用,因为我想在枚举期间删除元素。我可以通过一种解决方法(Intelligent way of removing items from a List<T> while enumerating in C#)解决这个问题,但对我来说整个表达看起来很糟糕。

第二个解决方案(最后一行代码)不存在,但类似的东西会很棒。

我希望你有更好的解决方案,我想与LINQ合作。性能是稳定的。

我考虑过合并两个列表并用主键对它们进行分组,但后来我必须删除databaseList中的元素,但是我怎么知道databaseList中有哪些元素。

一如既往有数百种方法可以解决这个问题,但是我找到了一个(第一个带有解决方法的解决方案),但也许有更优雅的方式。

2 个答案:

答案 0 :(得分:2)

最初,您可以列出已有的所有ID:

var ids = data.Repository.GetAllElements().Select(x=>x.Id);

然后您可以简单地执行以下操作:

foreach(var element in listOfRandomElements)
{
    // Check if there isn't any id in the ids collection which is equal to element's id.
    if(!ids.Any(x=>x==element.Id)
        // Here you could insert your element.
}

<强>更新

listOfRandomElements.RemoveAll(x=>ids.Contains(x.Id));

答案 1 :(得分:1)

对于那些正在寻找完整解决方案的人。特别感谢@Christos!

var databaseList = database.Repository.GetAllElements();
var keys = databaseList.Select(x => new {x.key0, x.key1, x.key2}); 

listOfElements.RemoveAll(
                x =>
                keys.Any(
                k => k.key0 == x.key0 && 
                k.key1 == x.key1 && 
                k.key2 == x.key2 ));

在此处找到提示:LINQ to Entities - where..in clause with multiple columns

编辑:没有必要先提取密钥。可以使用完整的databaseList而不是密钥。