C# 使用Linq比较列表并获取值

C# 使用Linq比较列表并获取值,c#,.net,linq,C#,.net,Linq,我的对象是“MyClass”,有两个属性:Id(int)和HourBy(int) 我有两份清单: var List1 = new List<MyClass>(); var List2 = new List<MyClass>(); 谢谢,您可以通过以下Linq声明来实现这一点: var result = List1.Where(x => !List2.Select(y => y.Id).Contains(x.Id) || List2.Single(y

我的对象是“MyClass”,有两个属性:Id(int)和HourBy(int)

我有两份清单:

var List1 = new List<MyClass>();
var List2 = new List<MyClass>();

谢谢,

您可以通过以下Linq声明来实现这一点:

var result = List1.Where(x => !List2.Select(y => y.Id).Contains(x.Id)
    || List2.Single(y => x.Id == y.Id).HourBy < x.HourBy);
var result=List1.Where(x=>!List2.Select(y=>y.Id).Contains(x.Id)
||列表2.Single(y=>x.Id==y.Id).HourBy

最诚挚的问候

根据您提供的示例列表,我认为这就是您所追求的

var list3 = new List<MyClass>();

foreach(var item in list1)
{
   var totalFromOther = list2.Where(x => x.id == item.id).Sum(y => y.HourBy);
   var newItem = new MyClass() { id = item.Id, HourBy = item.HourBy - totalFromOther };
   if(newItem.HourBy > 0)
     list3.Add(newItem);
}
var list3=新列表();
foreach(列表1中的变量项)
{
var totalFromOther=list2.Where(x=>x.id==item.id).Sum(y=>y.HourBy);
var newItem=new MyClass(){id=item.id,HourBy=item.HourBy-totalFromOther};
如果(newItem.HourBy>0)
列表3.添加(新项);
}
这里有一个解决方案:

        var qry = from ee in
                       (from e1 in list1
                        join e2 in list2 on e1.Id equals e2.Id into gj
                        from e in gj.DefaultIfEmpty()
                        select new { 
                            e1.Id,
                            MainHourBy = e1.HourBy,
                            SecondHourBy = (e == null ? 0 : e.HourBy)
                        })
                   where ee.SecondHourBy < ee.MainHourBy
                   group ee by ee.Id into g
                   select new MyClass
                   {
                       Id = g.Key,
                       HourBy = g.First().MainHourBy - g.Sum(el => el.SecondHourBy)
                   };
var qry=来自ee in
(来自列表1中的e1)
将e1.Id等于e2.Id的列表2中的e2连接到gj中
来自gj.DefaultIfEmpty()中的e
选择新{
e1.Id,
main HourBy=e1.HourBy,
SecondHourBy=(e==null?0:e.HourBy)
})
其中ee.SecondHourByel.SecondHourBy)
};
//组列表2,因此每个ID有一个条目,HourBy=每个ID的总小时数
var summedL2=来自列表2中的项2
按item2.ID将item2分组到g中
选择新测试(g.Key,g.Sum(item=>item.HourBy));
var结果=
//从列表1中选择项目
来自列表1中的项目1
//左键加入我们的汇总列表2
将item1.ID等于item2s.ID的summedL2中的item2s连接到tempItem2s中
来自tempItem2s.DefaultIfEmpty()中的item2
//如果没有匹配项,或项目2<项目1
其中(item2==null | | item2.HourBy
我使用这段代码,它并不完美,但很有效,对于Linq的新手(像我一样)来说可能更清晰

ListlistRes=newlist();
foreach(列表1中的MyClass项)
{
var exist=list2
.选择(x=>x.MyClass)
.包含(项目);
如果(!存在)
增加(项目);
其他的
{
var totalFromOther=list2
.Where(x=>x.MyClass.Id==item.Id)
.Sum(y=>y.HourBy);
如果(item.HourBy!=来自其他的总计)
{        
item.HourBy=item.HourBy-来自其他的总计;
增加(项目);
}            
}   
}

感谢您的帮助,

您能确认这是您想要的吗?…您想要返回列表1中的所有项目,这些项目存在于列表2中,但在列表2中的HourBy属性值较低,以及列表2中的所有项目,但不在列表1中?我同意,文字解释不是很清楚,但示例更清楚地显示了要求。我发现人们在回答问题时使用的不同方法很有趣(尽管它们在功能上并不完全相同)@James:让我试着重新措辞。List1作为对象,List2包含List1的某个对象的副本。列表2可以包含同一对象的多个时间段。我想要一个列表,列出列表2中不存在的对象,如果存在(一个或多个),则some必须等于列表1中的值(HourBy)。如果不存在,则对象出现在结果列表中,且列表1和列表2中的HourBy之差(Id之和)@MattH:同意,样本更清晰:)@Kris,好吧,我想我知道你想做什么。让我更新我的答案!我对“let”条款不太熟悉。它是为查询计算一次,还是在这种情况下每行计算一次?嘿,Oliver,我在我的项目中创建了我的linq查询,根据您的示例,它对我有帮助。谢谢
var agg1 = from l in list1
           group l by l.ID into g
           select new { g.Key, Sum = g.Sum(_ => _.HourBy) };
var agg2 = from l in list2
           group l by l.ID into g
           select new { g.Key, Sum = g.Sum(_ => _.HourBy) };

var q = from l1 in agg1
        let l2 = agg2.FirstOrDefault(_ => _.Key == l1.Key)
        let sum = l1.Sum - (l2 != null ? l2.Sum : 0)
        where sum != 0
        select new MyClass(l1.Key, sum);

var list3 = q.ToList();
        var qry = from ee in
                       (from e1 in list1
                        join e2 in list2 on e1.Id equals e2.Id into gj
                        from e in gj.DefaultIfEmpty()
                        select new { 
                            e1.Id,
                            MainHourBy = e1.HourBy,
                            SecondHourBy = (e == null ? 0 : e.HourBy)
                        })
                   where ee.SecondHourBy < ee.MainHourBy
                   group ee by ee.Id into g
                   select new MyClass
                   {
                       Id = g.Key,
                       HourBy = g.First().MainHourBy - g.Sum(el => el.SecondHourBy)
                   };
//Group list 2, so there is one entry per ID, with HourBy = total hour by
var summedL2 = from item2 in List2
              group item2 by item2.ID into g
              select new Test(g.Key, g.Sum(item => item.HourBy));

var result = 
            //Select items from list1
             from item1 in List1
             //Left join to our summed List2
             join item2s in summedL2 on item1.ID equals item2s.ID into tempItem2s
             from item2 in tempItem2s.DefaultIfEmpty()
             //Where there is no match, or item2 is < item1
             where (item2 == null || item2.HourBy < item1.HourBy)
             //Select a new Test object, with the HourBy changed
             select new Test(item1.ID, item1.HourBy - (item2 == null ? 0 : item2.HourBy));
List< MyClass> listRes = new List< MyClass>();
foreach ( MyClass item in list1)
{
    var exist = list2
        .Select(x => x.MyClass)
        .Contains(item);

    if (!exist)
        listRes.Add(item);
    else
    {
        var totalFromOther = list2
            .Where(x => x.MyClass.Id == item.Id)
            .Sum(y => y.HourBy);

        if (item.HourBy != totalFromOther)
        {        
            item.HourBy = item.HourBy - totalFromOther;
            listRes.Add(item);
        }            
    }   
}