【问题标题】:.net Core 2.2 EF: SaveChangesAsync() setting unrelated columns to null.net Core 2.2 EF:SaveChangesAsync() 将不相关的列设置为 null
【发布时间】:2020-06-15 08:09:03
【问题描述】:

我有一个 Asp.Net Core 2.2 应用程序。我编写了几个新的 Razor 页面来将一些新数据更新到现有模型。

问题在于,当我“提交”表单并调用 SaveChangesAsync() 时,它会更新我已更改的字段......并且它ERASES 记录中的大多数其他字段。

模型有 40 或 50 个属性;我只尝试更新其中的 3 或 4 个。

但是一切除了“ID”和我表单中的字段被更新设置为“null”。

问:知道我缺少什么吗?

public class EditPageModel : PageModel
{
    private readonly Project.Models.MyContext _context;

    [BindProperty]
    public MyModel MyRecord { get; set; }

    public EditPageModel(Project.Models.MyContext context)
    {
        _context = context;
        // <= This is OK...

    public async Task<IActionResult> OnGetAsync(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        MyRecord = await _context.MyModel.FirstOrDefaultAsync(m => m.ID == id);
        // <= This is OK, too: I call "return Page()" and everything looks fine...

    public async Task<IActionResult>OnPostAsync()
    {
        if (!ModelState.IsValid)
        {
            return Page();
        }

        // Update DB
        _context.Attach(MyRecord).State = EntityState.Modified;
        try
        {
            await _context.SaveChangesAsync();  
        }
        catch (DbUpdateConcurrencyException)
        {
            // No exceptions, no errors or warnings: Never get here...
            ...
        }
        return RedirectToPage("./Index");

【问题讨论】:

  • MyRecordonPostAsync 方法的开头是什么样的?你能告诉我们你的客户代码吗?
  • “MyRecord”中的大部分字段都是空的,这很有意义:如果视图不需要显示数据,EF 不应该获取它。但是为什么 EF 不够聪明,不能更新那些它没有获取的字段???
  • 但是您告诉 EF 在您的代码中将这些字段设置为 null。当您从客户端传入带有空值的模型时,您就这样做了。这就是模型绑定的工作原理。仅当您需要更新时才从数据库中获取实体,并且仅更新这 3 个字段并调用 SaveChanges()。不要这样传递,你会得到意想不到的结果。在这种情况下,模型绑定是更新实体时必须考虑的额外层。

标签: c# asp.net-core entity-framework-core


【解决方案1】:

你有两个选择:

选项 1:为模型中不需要更改的每个属性添加隐藏字段。

选项 2:从数据库加载记录,将模型中的属性映射到 db 对象并保存更改,而不将绑定模型附加到上下文。

【讨论】:

  • PS:你可以试试这个:endyourif.com/updating-specific-fields-using-entity-framework。老实说,不知道它是否也适用于 ef core,但它可能。
  • 是的——你说的完全正确。 “MyRecord”中的大多数字段都是空的,这很有意义:如果视图不需要显示数据,则 EF 不应该获取它。但是为什么 EF 不够聪明,不能更新那些它没有获取的字段???无论如何,dbEntry.Property(includeProperty).IsModified = true; 就像一个魅力 :) 谢谢 :)
  • 基本上,当您_context.Attach(MyRecord).State = EntityState.Modified; 时,您是在告诉 EF“整个对象已更改”,因此 EF 在 UPDATE 语句中发送所有字段。相反,通过首先查询对象,您将获得一个实现 INotifyPropertyChanged 的​​代理类,它允许 DbContext 更改跟踪器了解每个实体中的更改内容,同时跟踪旧值和新值。
猜你喜欢
  • 1970-01-01
  • 2019-12-02
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多