C# 如何更新中的所有位置

C# 如何更新中的所有位置,c#,linq,lambda,entity-framework-6,C#,Linq,Lambda,Entity Framework 6,以下是我在数据库中的一些表 用户(UserEmail,…)蛋糕(CakeId,姓名,股票,…) 购物车(UserEmail,CakeId,…) 如何使lambda表达式与SQL查询匹配: UPDATE Cake SET Stock = Stock - 1 WHERE CakeId IN (SELECT CakeId FROM Cart WHERE UserEmail = "someone@example.com") 在实体框架中 基本上,我希望将当前登录用户购物车中的所有蛋糕库存减少1。尝试

以下是我在数据库中的一些表

用户(UserEmail,…)
蛋糕(CakeId,姓名,股票,…)
购物车(UserEmailCakeId,…)

如何使lambda表达式与SQL查询匹配:

UPDATE Cake 
SET Stock = Stock - 1
WHERE CakeId IN (SELECT CakeId FROM Cart WHERE UserEmail = "someone@example.com")
在实体框架中

基本上,我希望将当前登录用户购物车中的所有蛋糕库存减少1。

尝试如下操作:

   var cakes = (from c in dataContext.Cakes
    join ca in dataContext.Carts on c.cakeId equals ca.cakeId
    where ca.UserEmail = "someone@example.com"
    select c);

    foreach(Cake c in cakes)
    {
       c.Stock--;
    }

您可以获取股票,并使用foreach循环更新它

//begin transaction
var context = DBcontext.Database.BeginTransaction();
//Select cakes that contains useremail "" in their carts 
var cakes = DBcontext.Cakes.where(c => c.Carts.Any(x => x.UserEmail == "someone@example.com"));
// Loop through
foreach (var cake in cakes)
{
cake.Stock--;
//then update context 
DBcontext.Entry(cake).State = EntityState.Modified;
}
//Then save changes 
DBcontext.SaveChanges();
//then commit the transaction
context.commit();

免责声明:我是项目的所有者

此库具有批量更新功能,这正是您需要的

下面是一个如何使用它的示例

ctx.Cake.Where(x => x.UserEmail = "someone@example.com")
        .Update(x => new Cake() { Stock = x.Stock - 1 });
将更新所有行,而不在内存中加载实体


Wiki:

例如,您可以让EF直接运行SQL。或者,您可以使用从SQL查询生成EF代码。lambda用于查询。如果要执行批处理更新,请使用原始SQL。EF(和所有ORM)处理单个对象。它们不适合批量操作。您必须加载所有对象,更新每个对象,然后将所有更改保存回数据库。这不是EF限制,这对所有ORM都是一个问题。您也不需要子查询,请在Cake.CakeID=Cart.CakeID WHERE UserEmail=…'上使用来自Cake内部的
加入Cake.CakeID,除非保存更改,否则不会更新任何内容。这也是最低效的更新方式——加载内存中的所有对象只是更新一个值,然后将所有内容发送回内存。simpe
updatemytable SET Stock=Stock-1
会快得多,使用ORMs连接是一种非常强烈的气味。这意味着实体之间的关系缺失。
Cake
应该有一个
Cart
属性,该属性允许您编写
where-Cake.Cart.UserEmail=…
。LINQ不是SQLQ的替代品。它不执行批处理更新,它加载内存中的所有对象,更新一个属性,然后将所有内容写回。这是N个不同的更新语句。您也不需要事务,SaveChanges使用自己的事务
Cakes
已经是可查询的。这不是可查询的vs可枚举的。此代码加载所有相关对象,修改它们,然后将它们写回。UPDATE语句只会直接修改相关字段,而不加载任何内容。这是所有ORM的一个基本限制。对于N行,您有一个大的负载和N个单独的更新现在我很抱歉我的不好,我不知道您在寻找什么,我不确定是否可以使用实体框架,我将与您一起等待答案:)我不是OP。我是说这是一个坏主意和一个非常常见的错误。EF允许您以任何可能听说过N+1问题的方式执行原始SQL语句?这是一个类似的例子