【问题标题】:Run Update Statement Using Entity Framework Linked Table使用实体框架链接表运行更新语句
【发布时间】:2020-06-25 22:27:27
【问题描述】:

使用 EF Core 控制台应用程序,我需要让管理员用户能够选择一个复选框,然后在按下按钮时,基本上运行这个伪代码语句

update EF Table set active = 'Yes' where userID = userID of checkbox

使用 EF 运行 Select 没有问题,但如何进行更新?

编辑
我目前有这个语法

foreach ((int Id, DateTime? submissionDate, string status) tuple in apiData)
{
    if (ctx.Test.Any(x => x.OrderId == tuple.Id))
    {
        Test ts = new Test();
        ts.Status = tuple.status;
        ctx.Test.Add(ts);
        ctx.SaveChanges();
    }
    else
    {
        Test ts = new Test();
        ts.OrderId = tuple.Id;
        ts.PdfDownloaded = tuple.submissionDate;
        ts.Status = tuple.status;
        ctx.Test.Add(ts);
        ctx.SaveChanges();
    }
}

但是当我运行代码时,我在更新(if)时收到此错误。

System.InvalidOperationException:“无法跟踪实体类型“Test”的实例,因为已经在跟踪具有相同键值 {'OrderId'} 的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。考虑使用“DbContextOptionsBuilder.EnableSensitiveDataLogging”来查看冲突的键值。'

编辑 2
这种方法我也试过了

var records = ctx.Test.Where(x => x.OrderId == tuple.Id);
records.ForEach(x => x.Status = tuple.status);
ctx.SaveChanges();

但我在foreach 上收到此编译错误

“IQueryable”不包含“ForEach”的定义,并且找不到接受“IQueryable”类型的第一个参数的可访问扩展方法“ForEach”(您是否缺少 using 指令或程序集引用?)

【问题讨论】:

  • SaveChanges 保存所有修改。它不应该在循环中调用。至于第二个错误,ForEach 是一个List<T> 方法。您需要先将数据加载到列表中,尽管您可以使用 foreach 并修改每个对象而不将其放入列表中

标签: c# entity-framework-core


【解决方案1】:

您应该首先获取要更新的记录

var records = context.EFTable.Where(x => x.userID == UserId).ToList();

那么你应该在所有这些对象上将 active 设置为 yes

records.ForEach(x => x.active = "yes");

最后,保存所有更改

context.saveChanges();

【讨论】:

  • 在我的编辑中,我不是在抓取我要更新的记录吗?
  • 不,在您的编辑中,您没有抓取记录,就像我在答案的第一行代码中所做的那样。你能把Test ts = new Test();改成Test ts = ctx.FirstOrDefault(x => x.OrderId == tuple.Id);
  • 这给了我'DataBankContext' does not contain a definition for 'FirstOrDefault' and no accessible extension method 'FirstOrDefault' accepting a first argument of type 'DataBankContext' could be found (are you missing a using directive or an assembly reference?) 的错误
  • 要修复该错误,您应该添加 System.Linq 命名空间。有关这方面的更多信息,请查看link
  • 我把那部分弄清楚了。我需要做ctx.Test.FirstOrDefault()
【解决方案2】:

还有 将 SaveChanges 置于循环之外

【讨论】:

    【解决方案3】:
    var entity = context.table.WHERE(userId == checkBox).FirstOrDefault();
    
    entity.property = "value"
    context.saveChanges();
    

    【讨论】:

    • where 是如何发挥作用的,所以我只更新了一个?
    • 您不需要使用“WHERE”。该框架将自动生成。 (您无法控制,实际上会生成 SQL 语句。这就是为什么实体的结构比普通查询慢的原因)
    • 我还是不明白。我想使用if else 语句,并且我正在检查表中是否已经存在userID,那么我们需要更新,如果用户ID 不存在,那么我们需要插入。我已经把插入语法记下来了,但我无法把注意力集中在update
    • 请把你完整的实体类测试贴出来。
    • 这没有提供问题的答案。要批评或要求作者澄清,请在他们的帖子下方留下评论。 - From Review
    猜你喜欢
    • 2010-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多