【问题标题】:Entity Framework Core set Navigation property to null with include doesn't work实体框架核心将导航属性设置为 null 并包含不起作用
【发布时间】:2019-06-24 00:53:01
【问题描述】:

我正在尝试重置资产实体中的项目导航属性。

资产模型(删除所有不相关的内容):

public class Asset
{
    public int Id { get; set; }
    public int? ProjectId { get; set; }
    public Project Project { get; set; }
}

重置逻辑:

var asset = await context.Assets.Include("Project").FirstAsync(a => a.Id == assetId);
asset.Project = null;
asset.ProjectId = null;
await context.SaveChangesAsync();

我将项目包含在查询中并尝试将 Project 和 ProjectId 设置为 null,但它没有在数据库中更新。此外,我已经尝试仅设置项目,仅将 ProjectId 设置为 null,但均无效。

对于这个问题有一些关于 SO 的相关问题,但对于所有这些问题, Include("xy") 似乎都可以解决问题。

【问题讨论】:

  • 你能粘贴你得到的错误吗?
  • ProjectId 是主键吗?如果是这样,我认为您不能将其设置为 null
  • 只有当我想使用 Microsoft.EntityFrameworkCore.Proxies 进行延迟加载时才需要虚拟,但我不想延迟加载。据我所知,使用 .Include("xy") 它会急切地加载导航属性。
  • 是的,我发现了问题。我设置 context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;在上下文生命周期的某个时刻。有趣的是,在我提出一个 SO 问题之后,这些事情总是出现,而不是在 xD 之前搜索问题的几个小时内出现
  • 就可以了 :) 感谢您来回提出一些想法。

标签: c# entity-framework-core


【解决方案1】:

很容易解决,但很难追踪。我打电话给 context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;在之前的某个时间点上的上下文,这使得结果只读。 source

两种解决方案:

  • 要么删除这条线(对我来说,这是玩游戏的剩余部分),
  • 如果您想保持一般的无跟踪行为,则将 .AsTracking() 添加到查询中。

上面的例子看起来像:

var asset = await context.Assets.Where(a => a.Id == assetId).Include("Project")
                                .AsTracking().FirstOrDefaultAsync()
asset.Project = null;

如果您的模型上有可用的外键,您可以删除包含并将外键设置为 null,如下所示:

var asset = await context.Assets.Where(a => a.Id == assetId).AsTracking().FirstOrDefaultAsync()
asset.ProjectId = null;

再次没有 context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;您可以省略 .AsTracking() 因为这是标准行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-08
    相关资源
    最近更新 更多