C# 实体框架核心导航属性不保持空

C# 实体框架核心导航属性不保持空,c#,entity-framework,entity-framework-core,C#,Entity Framework,Entity Framework Core,我有一个带有链接类的类,例如想象一个人和一条狗。它在PersonDto中的映射如下: public int? DogId { get; set; } public virtual DogDto Dog { get; set; } 对于许多人来说,DogId是空的,但在我亲自更改某些内容并执行SaveChanges之后,实体框架坚持它应该插入一个空条目 我的场景要大得多,但简化了,它可能是这样的: var person = await _entities.Persons.Where(p =>

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

public int? DogId { get; set; }
public virtual DogDto Dog { get; set; }
对于许多人来说,DogId是空的,但在我亲自更改某些内容并执行SaveChanges之后,实体框架坚持它应该插入一个空条目

我的场景要大得多,但简化了,它可能是这样的:

var person = await _entities.Persons.Where(p => p.Name == "Ann")
            .Select(p => p).Include(p => p.Dog).First();
person.Name = "Bob";
_entities.SaveChanges();
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;
现在想象一下,安没有狗,DogId应该保持为空

SQL实体框架核心执行如下插入:

var person = await _entities.Persons.Where(p => p.Name == "Ann")
            .Select(p => p).Include(p => p.Dog).First();
person.Name = "Bob";
_entities.SaveChanges();
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;

我错过了什么。不会吧?是否足以允许它为空

我只想发布一个答案,以防搜索到此结束


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

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