Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.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# 比较两个列表中对象的属性_C#_.net_Linq_Linq To Entities - Fatal编程技术网

C# 比较两个列表中对象的属性

C# 比较两个列表中对象的属性,c#,.net,linq,linq-to-entities,C#,.net,Linq,Linq To Entities,我有以下(简化)课程: 我只想比较两个CareRate列表的DayRate;一个带有CareRates的,包含当前DayRates的,一个带有CareRates的,包含要更新的DayRates。其他可能已更改的属性(如描述)不应考虑在内 // Just a test method public List<CareRate> FilterChangedCareRates(){ var currentCareRates = new List<CareRate>{

我有以下(简化)课程:

我只想比较两个
CareRate
列表的
DayRate
;一个带有
CareRates
的,包含当前
DayRates
的,一个带有
CareRates
的,包含要更新的
DayRates
。其他可能已更改的属性(如描述)不应考虑在内

// Just a test method
public List<CareRate> FilterChangedCareRates(){
    var currentCareRates = new List<CareRate>{
        new CareRate { Id = 1, DayRate = 3,33, Description = "Some descr" }, 
        new CareRate { Id = 2, DayRate = 4,44, Description = "Some other descr" } 
    };

    var updatedCareRates = new List<CareRate>{
        new CareRate { Id = 1, DayRate = 2,22 }, 
        new CareRate {Id = 2, DayRate = 4,44 } // Unchanged
   };

    var actualUpdatedCareRates = new List<CareRate>();

    foreach(var updatedCareRate in updatedCareRates) {
        var currentCareRate = currentCareRates.Single(x => x.Id == updatedCareRate.Id); 
        if (updatedCareRate.DayRate != currentCareRate.DayRate) {
            actualUpdatedCareRates.Add(updatedCareRate); 
        }
    }
    return actualUpdatedCareRates;
}
//只是一种测试方法
公共列表筛选器更改费率(){
var currentCareRates=新列表{
新的CareRate{Id=1,DayRate=3,33,Description=“Some descr”},
新的CareRate{Id=2,DayRate=4,44,Description=“Some other descr”}
};
var updatedCareRates=新列表{
新的监护率{Id=1,DayRate=2,22},
新的监护率{Id=2,DayRate=4,44}//未改变
};
var actualUpdatedCareRates=新列表();
foreach(updatedCareRates中的var updatedCareRate){
var currentCareRate=currentCareRates.Single(x=>x.Id==updatedCareRate.Id);
if(updatedCareRate.DayRate!=currentCareRate.DayRate){
actualUpdatedCareRates.Add(updatedCareRate);
}
}
返回实际更新的利率;
}

Dayrate
过滤已更改的
CareRate
对象的方式感觉有点迂回。我想我忽略了什么。有什么其他更好的选择可以获得上述信息?

我认为,您可以使用以下内容:

updatedCareRates.ForEach(x =>
{
    if (currentCareRates.FirstOrDefault(y => y.Id == x.Id && y.DayRate != x.DayRate) != null)
        actualUpdatedCareRates.Add(x);
});
或者在一行中:

updatedCareRates.Where(x => currentCareRates.FirstOrDefault(y => y.Id == x.Id &&
                            y.DayRate != x.DayRate) != null).ToList()
                           .ForEach(x => actualUpdatedCareRates.Add(x));
在LINQ中简单使用方法:

var actualUpdatedCareRates = currentCareRates.Zip(updatedCareRates, 
                             (f, s) => f.DayRate != s.DayRate ? s : null)
                             .Where(c => c != null).ToList();
您可以使用以下选项:

return (from up in updatedCareRates
            join cur in currentCareRates
            on up.Id equals cur.Id
            where up.DayRate != cur.DayRate
            select up).ToList();

这里是我认为查询语法优于方法语法的罕见案例之一。

我没有使用
where(x=>x…)
,而是使用
方法寻找解决方案,但发布的
方法除外

我创建了一个类
DayRateComparer
,如下所示

public class DayRateComparer : IEqualityComparer<CareRate>
{
    public bool Equals(CareRate x, CareRate y) {
        if (x = null) throw new ArgumentNullException(nameof(x));
        if (y = null) throw new ArgumentNullException(nameof(y));

        return x.Id == y.Id && x.DayRate == y.DayRate;
    }

    public int GetHashCode(CareRate obj) {
        retun obj.Id.GetHashCode() + obj.DayRate.GetHashCode(); 
    }
}

我不喜欢使用临时列表(如
actualUpdatedCareRates
),在使用比较器时,这不再是必需的。所提到的
Zip
方法也是一种简洁的方法,但乍一看有点复杂。谢谢大家的发帖。

我不太确定你想用你提到的列表做什么。。您是在查看费率发生变化的项目列表,还是使用新费率更新了所有原始项目的列表?这似乎是一个回顾。可能应该转到CodeReview.change。com@BugFinder希望有一个只更改了DayRate(与当前DayRate相比)的CareRate的新列表。您可以在一行中执行此操作:
return updatedCareRates.Where(updated=>currentCareRates.Any(current=>current.DayRate!=updated.DayRate))
@HimBromBeere Codereview.stackexchange.com,是的。那边最好是非简化版,请参考。No
Zip
并不像你想象的那么复杂。去看看我在回答中提到的链接是如何工作的。它使您的工作比为此编写比较器容易得多,同时您可以轻松地使用
Zip
方法IMO.@S.Akbari,您是对的。它没有那么复杂,它做了它应该做的事情。我把你的答案标为解决办法。
public class DayRateComparer : IEqualityComparer<CareRate>
{
    public bool Equals(CareRate x, CareRate y) {
        if (x = null) throw new ArgumentNullException(nameof(x));
        if (y = null) throw new ArgumentNullException(nameof(y));

        return x.Id == y.Id && x.DayRate == y.DayRate;
    }

    public int GetHashCode(CareRate obj) {
        retun obj.Id.GetHashCode() + obj.DayRate.GetHashCode(); 
    }
}
// Just a test method
public List<CareRate> FilterChangedCareRates(){
    var currentCareRates = new List<CareRate>{
        new CareRate { Id = 1, DayRate = 3,33, Description = "Some descr" }, 
        new CareRate { Id = 2, DayRate = 4,44, Description = "Some other descr" } 
    };

    var updatedCareRates = new List<CareRate>{
        new CareRate { Id = 1, DayRate = 2,22 }, 
        new CareRate {Id = 2, DayRate = 4,44 } // Unchanged
   };

    return updatedCareRates.Except(currentCareRates, new DayRateComparer()).ToList();
}