如何在单个 lambda 表达式中同时使用更新和加入 [关闭]
Posted
技术标签:
【中文标题】如何在单个 lambda 表达式中同时使用更新和加入 [关闭]【英文标题】:How to use both update and join in a single lambda expression [closed] 【发布时间】: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;
【问题讨论】:
如果您尝试过,请告诉我们,并解释为什么它不起作用。 至少尝试编写代码。您想在 LINQ 中使用 join 或包含:docs.microsoft.com/en-us/dotnet/csharp/language-reference/… 并且可以使用 ORM 或 ADO.Net 进行更新:***.com/questions/46657813/… AFAIK 开箱即用 EF 不支持此类查询。你可以寻找一些像 bulk extensions 或 entity framework extensions 这样的库,它们可能支持这样的东西。 在原始 EF Core 中是不可能的。但是一些extensions 可能会有所帮助。我推荐linq2db.EntityFrameworkCore。请参阅文档:Update、Join 【参考方案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。以上是关于如何在单个 lambda 表达式中同时使用更新和加入 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
如何使用lambda表达式/缩短onclicklisteners android studio