【问题标题】:Match and update values using linq from two lists?使用两个列表中的 linq 匹配和更新值?
【发布时间】:2014-02-15 12:49:12
【问题描述】:

您好,我是 c# 和 Linq 的新手。如果某个属性的值与另一个列表属性的值匹配,我正在尝试更新一个列表。

假设我有一个列表为firstlist

   Name      code        
   ABC       101         
   DEF       201         
   GHI       301
   JKL       401
   MNO       101 

第二个列表为secondlist

  description       Code
    IT               101
    ADMIN            201
    Develeopment     301
    Testing          401
    Service          501

我希望我的结果列表为

    Name      code        
    ABC       101 IT        
    DEF       201 ADMIN       
    GHI       301 Develeopment
    JKL       401 Testing
    MNO       101 IT

我试过这样的,

    var query = firstlist.Select(x => { x.Code = 101; return x.Code.ToString()+"IT"; })

但是我想匹配来自secondlist 的代码来代替101 并且为了匹配代码我想用code+description 更新firstlist 代码我不知道该怎么做如果有人提出任何可以指导我的方式或链接,那就太好了。

*******更新* ******

我想说的是,正如@Sergey 建议的那样

   from x in firstlist
   join y in secondList
   on x.code equals y.Code
   select new {
       x.Name,
      code = String.Format("{0} {1}", y.Code, y.description)   
  }

我可以做这样的事情来代替它吗

   from x in firstlist
   join y in secondList
   on x.code equals y.Code
   select x.code = String.Format("{0} {1}", y.Code, y.description)   

这只会更新现有的listone,而不是为每个匹配项创建新实体

【问题讨论】:

  • 如果您有多个匹配项怎么办?或者如果某个值没有匹配项?
  • @SergeyBerezovskiy 不。我在secondlist 中有不同的值。假设SecondList是主表数据,firstlist是明细表数据

标签: c# performance linq c#-4.0


【解决方案1】:

使用Enumerable.Join 获取两个列表中匹配的项目:

from x in firstlist
join y in secondList
   on x.code equals y.Code
select new {
   x.Name,
   code = String.Format("{0} {1}", y.Code, y.description)   
}

更新第一个列表中的对象:

var query = from x in firstlist
            join y in secondList
                on x.code equals y.Code
            select new { x, y };

foreach(var match in query)
   match.x.Code = String.Format("{0} {1}", match.y.Code, match.y.description);

【讨论】:

  • 如果我在listone 中有很长的属性列表,我是否必须像这样在code = String.Format("{0} {1}", y.Code, y.description),someprop1,someprop2,someprop3 中提及所有这些属性
  • @Curiosity 如果您谈论的是firstlistx 的属性,那么您只需在结果中选择x 实体:select new { x, y }
  • @Curiosity someprop1, someprop2 来自哪里?
  • 它们是firstlist 中除名称和代码之外的额外属性,所以我要说的是为每个匹配项创建新实体,我可以通过执行更新code 的现有值吗类似x.code=y.code+y.description
  • @Curiosity 如果要更新firstlist中的项目,则可以枚举查询结果并更新x.Code
【解决方案2】:

Code 似乎是int,那么您不能将其更改为包含代码+描述的string。所以这个方法假定它是一个string

您可以使用Enumerable.Join 仅获取符合Code 的项目。那么最高效的就是使用一个简单的循环来用新值更新属性:

var firstInSecond = from first in firstlist
                    join second in secondList
                    on first.Code equals second.Code
                    select new { first, second };
foreach (var x in firstInSecond)
    x.first.Code = string.Format("{0} {1}", x.second.Code, x.second.Description);

【讨论】:

    【解决方案3】:

    暂时将描述列添加到firstlist或将其克隆到另一个表

    firstlist.Columns.Add("description");
    Datatable joinedTable = from first in firstlist
                        join second in secondList
                        on first.Code equals second.Code
                        select new DataRow[] { first , second }).Select(resultSet =>
                                              {
                                                  resultSet[0]["description"] = resultSet[1]["description"];
                                                  return resultSet[0];
                                              }).CopyToDataTable();
    

    【讨论】:

      【解决方案4】:

      对于使用 AND 查询在 2 个列表上使用 JOIN 进行更新,您可以使用 JOIN 和 Where 条件,请查看以下示例, https://codeshowtime.blogspot.com/2020/01/linq-tricks.html

      【讨论】:

        猜你喜欢
        • 2019-10-27
        • 1970-01-01
        • 1970-01-01
        • 2021-09-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多