【问题标题】:How to use both update and join in a single lambda expression [closed]如何在单个 lambda 表达式中同时使用更新和加入 [关闭]
【发布时间】:2021-07-28 15:17:05
【问题描述】:

我想将我的 SQL 查询转换为 lambda 表达式。下面是 SQL 查询。我试过但未能得到预期的结果

UPDATE
    Sales
SET
    SI.ACP= SD.ACP
FROM
    Sales SI
INNER JOIN
    SaleDesc SD
ON 
    SI.GroupID= SD.GroupID;

【问题讨论】:

标签: c# linq lambda entity-framework-core


【解决方案1】:

EF Core 本身不支持批量和本机更新,一切都应通过 ChangTracker。

无论如何,您可以使用 EF Core 的可用扩展,它可以在不执行原始 SQL 的情况下做到这一点。例如linq2db.EntityFrameworkCore(免责声明:我是创作者之一)

然后你可以编写如下的 LINQ 查询:

var queryForUpdate =
   from si in ctx.Sales
   join sd in ctx.SalesDesc on si.GroupID equals sd.GroupID
   select new { si, sd }

queryForUpdate
   .Set(u => u.si.ACP, u => u.sd.ACP)
   .Update();

【讨论】:

    【解决方案2】:

    销售必须有 PK。 你有不同的方式来编写 LINQ。这是其中一种方法(我试图让它对你来说更具可读性。)

    Sales.Dump("original");
        Sales
            .Join(
                    SaleDescs,
                    sales => sales.GroupID,
                    desc => desc.GroupID,
                    (sales, desc) => new { Sales = sales, SaleDesc = desc }
                )
                .ToList()
                .ForEach(s =>
                {
                    Sales.Where(sl => sl.GroupID == s.Sales.GroupID).FirstOrDefault().ACP = s.SaleDesc.ACP;
                });
                SubmitChanges();
                
        Sales.Dump("resulted");
    
    

    因为我没有关于表结构的详细信息 - 我为这个例子编了一些

    【讨论】:

      【解决方案3】:

      使用

      using (var db = new MyContext())
      {
        var p = db.Sales
              .Join(db.SaleDesc,
               left => left.GroupID,
               right => right.GroupID,
              (left, right) => new { Sales = left, ACP = right.ACP });
              
        foreach (var item in p)
        {
          item.Sales.ACP = item.ACP;
          db.Sales.Attach(item.Sales);
          db.Entry(item.Sales).State = EntityState.Modified;
          db.SaveChanges();
        }
      }
      

      using (var db = new MyContext())
      {
          db.Sales
          .Join(db.SaleDesc,
          left => left.GroupID,
          right => right.GroupID,
          (left, right) => new { Sales = left, ACP = right.ACP }).ForEachAsync(a => a.Sales.ACP = a.ACP);
          db.SaveChanges();
      }
      

      【讨论】:

      • 我希望你明白,如果有数千条记录,这将成为一场噩梦?
      • 不,我没有考虑过,但是我认为Update()方法在底层也是一样的。
      • 不,从我的答案更新生成与问题完全相同的 SQL,并且没有记录加载到客户端。在您的解决方案中,您加载所有内容,然后 EF 发送大量更新
      • 当你有"var queryForUpdate = ......",即你已经加载了记录,然后执行了更新操作。
      • 加载记录,你知道是由ToList、ToArray等发起的。这里我们只有IQueryable,它还没有执行。通过 Update 提供执行,生成适当的 UPDATE SQL。
      猜你喜欢
      • 2010-10-14
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-21
      相关资源
      最近更新 更多