Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# LINQ Except/Distinct仅基于少数列,不添加重复项_C#_.net_Linq_Distinct_Except - Fatal编程技术网

C# LINQ Except/Distinct仅基于少数列,不添加重复项

C# LINQ Except/Distinct仅基于少数列,不添加重复项,c#,.net,linq,distinct,except,C#,.net,Linq,Distinct,Except,请原谅我把标题弄糊涂了。但我想不出更简单的办法 我的功课不及格 public class Foo { public FooId int { get; set; } public FooField string { get; set; } //some more fields here.... //.... //.... public DateTime CreatedDate { get; set; } } 我需要循环一些内容,并将一系列的F

请原谅我把标题弄糊涂了。但我想不出更简单的办法

我的功课不及格

public class Foo
{
    public FooId int { get; set; }

    public FooField string { get; set; }

    //some more fields here....
    //....
    //....

    public DateTime CreatedDate { get; set; }
}
我需要循环一些内容,并将一系列的
Foo
添加到
列表中,但基于
FooId
FooField
的组合,它不应该重复

所以我尝试如下

List<Foo> foos = new List<Foo>();

foreach (Bar item in blah.Bars)
{
    //Some code here to get the foos from the item
    List<Foo> processedFoos = item.GetFoos();

    //The problem is with below line
    foos.AddRange(processedFoos.Except(foos));
}
List foos=new List();
foreach(条形图中的条形图项目)
{
//这里有一些代码可以从项目中获取foos
List processedFoos=item.GetFoos();
//问题出在底线以下
foos.AddRange(processedFoos.Except(foos));
}
Except
添加所有记录并复制
FooId
FooField
组合,因为
CreatedDate
对于所有记录都是唯一的

但是我需要忽略
CreatedDate
,只添加那些不违反唯一组合的记录

我能在这里做什么<代码>除了
<代码>不同的?还有其他选择吗


最重要的是,如何比较?

除了之外的
不同的
都将基于对象的
等于
实现来比较项目(这是默认的相等比较器)。它们还都有重载,这些重载采用
IEqualityComparer

您可以实现此接口(请参见示例),只比较所需的字段,并将其传递给除
之外的

 foos.AddRange(processedFoos.Except(foos, comparer));

Except
Distinct
都将基于对象的
Equals
实现来比较项目(这是默认的相等比较器)。它们还都有重载,这些重载采用
IEqualityComparer

您可以实现此接口(请参见示例),只比较所需的字段,并将其传递给除
之外的

 foos.AddRange(processedFoos.Except(foos, comparer));

您需要覆盖
Foo
中的
Equals
,或者实现
IEqualityComparer
,以便
Except
可以判断两个
Foo
值何时相等。例如:

public sealed class FooComparer : IEqualityComparer<Foo>
{
    public bool Equals(Foo x, Foo y)
    {
        return x.FooId == y.FooId && x.FooField == y.FooField;
    }

    public int GetHashCode(Foo foo)
    {
        // Note that if FooField can be null, you'll need to account for that...
        return foo.FooId ^ foo.FooField.GetHashCode();
    }
}

您需要覆盖
Foo
中的
Equals
,或者实现
IEqualityComparer
,以便
Except
可以判断两个
Foo
值何时相等。例如:

public sealed class FooComparer : IEqualityComparer<Foo>
{
    public bool Equals(Foo x, Foo y)
    {
        return x.FooId == y.FooId && x.FooField == y.FooField;
    }

    public int GetHashCode(Foo foo)
    {
        // Note that if FooField can be null, you'll need to account for that...
        return foo.FooId ^ foo.FooField.GetHashCode();
    }
}

我认为您应该改变选择不重复记录的方式:

processedFoos.Where(x => !foos.Any(y => y.FooId == x.FooId && y.FooField == x.FooField))

我认为您应该改变选择不重复记录的方式:

processedFoos.Where(x => !foos.Any(y => y.FooId == x.FooId && y.FooField == x.FooField))

Except
Distinct
都有一个重载,需要
IEqualityComparer
。您可以实现一个来只比较所需的属性

另一种方法是按FooId和FooField分组,并从每个组中获取第一个元素:

processFoos.GroupBy(foo => new {foo.FooId, foo.FooField})
.Select(g => g.First());

Except
Distinct
都有一个重载,需要
IEqualityComparer
。您可以实现一个来只比较所需的属性

另一种方法是按FooId和FooField分组,并从每个组中获取第一个元素:

processFoos.GroupBy(foo => new {foo.FooId, foo.FooField})
.Select(g => g.First());

实现
IEqualityComparer
并使用
Except()
的适当重载实现
IEqualityComparer
并使用
Except()
方法很好,但基于唯一的组合,它会得到不同的
processedFoos
。我需要检查
processedFoos
中是否存在重复的
foos
。谢谢你的回答。谢谢!我将实现
IEqualityComparer
,正如您和其他人所建议的,@Jon Skeet在他的回答中所演示的那样。
GroupBy().Select()
方法很好,但它会根据独特的组合得到不同的
processedFoos
。我需要检查
processedFoos
中是否存在重复的
foos
。谢谢你的回答。谢谢!我将实施
IEqualityComparer
,正如您和其他人所建议的,@Jon Skeet在他的回答中所展示的那样。