【问题标题】:Entity Framework Core naviagional property does not remain nullEntity Framework Core 导航属性不保持为空
【发布时间】:2018-09-17 16:56:13
【问题描述】:

我有一个带有链接类的类,例如想象一个带狗的人。它在 PersonDto 中是这样映射的:

public int? DogId { get; set; }
public virtual DogDto Dog { get; set; }

对于许多人来说,DogId 为空,但在我更改 Person 中的某些内容并执行 SaveChanges 之后,实体框架坚持认为它应该插入一个空白条目。

我的场景要大得多,但经过简化后可能如下所示:

var person = await _entities.Persons.Where(p => p.Name == "Ann")
            .Select(p => p).Include(p => p.Dog).First();
person.Name = "Bob";
_entities.SaveChanges();

现在假设 Ann 没有狗,DogId 应该保持为空。

SQL Entity Framework Core 执行如下 INSERT:

DECLARE @inserted0 TABLE ([Id] int, [_Position] [int]);
MERGE [Dogs] USING (
VALUES (@p0, @p1, @p2, @p3, @p4, 0),
(@p5, @p6, @p7, @p8, @p9, 1)) AS i ([Col1], [Col2], [Col3], [Col4], [Col5], 
_Position) ON 1=0
WHEN NOT MATCHED THEN
INSERT ([Col1], [Col2], [Col3], [Col4], [Col5])
VALUES (i.[Col1], i.[Col2], i.[Col3], i.[Col4], i.[Col5])
OUTPUT INSERTED.[Id], i._Position
INTO @inserted0;

我错过了什么。不会int吗?足以让它为空吗?

【问题讨论】:

  • 为什么选择时要包括一只狗?如果您只需要更改人名!
  • 我要试一试(我可能是错的),并说问题可能源于试图急切加载 (.Include(...)) 标记的导航属性作为虚拟,这意味着它是延迟加载的。你必须选择一个。而且由于默认情况下不启用延迟加载(因为它会导致像这样奇怪的副作用),除非您选择了延迟加载,否则您不应该使用 virtual 关键字。
  • 您是否使用Lazy loading proxies,即代码中某处有.UseLazyLoadingProxies() 配置调用?因为如果这样做,您将无法从导航属性中删除 virtual。您的“简化示例”也可以重现该问题吗?因为如果是,那就是 EF Core 错误。
  • 我支持@IvanStoev,因为如果不使用延迟加载,virtual 关键字应该 无效。我几乎可以肯定我已经看到了文档中所写的内容。但由于删除 virtual 关键字解决了问题,因此可能存在疏忽。
  • 我在 EF 团队工作,我猜不出会发生什么。我不希望虚拟与它有任何关系。但目前还不清楚症状是什么,或者您是否有任何其他配置,例如拥有的实体。可以同时使用急切加载和延迟加载。我想确保它不是错误,但要进行调查,我们需要一个能够重现该行为的项目。如果你能提供,请在GitHub.com/AspNet/EntityframeworkCore/issues/new 创建一个问题。您可以在问题中引用此线程。

标签: c# entity-framework entity-framework-core


【解决方案1】:

我只想发布一个答案,以防任何搜索在这里结束。

虚拟无关紧要是完全正确的,问题在于我的 Dto 和域层之间的一些映射,我错误地附加了一个空白条目。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-01-01
    • 2023-03-17
    • 1970-01-01
    • 2021-05-17
    • 1970-01-01
    • 2020-06-27
    • 1970-01-01
    相关资源
    最近更新 更多