EF核心3.1.1-拥有实体代理问题

问题描述 投票:1回答:1

我最近在EF核心3.1.1中遇到了一个奇怪的问题。我们正在尝试从EF6迁移到EF核心,拥有实体的行为与EF6中的复杂类型不同。当拥有的实体由空对象初始化时,EF无法检测到更改。仅针对MSSQL,针对“内存中”数据库,就会出现此问题,一切似乎都很好。

public class OwnedEntityProxyTests
{
    [Fact]
    public void InMemoryTest()
    {
        Assert.True(Test(new DbContextOptionsBuilder<TestContext>()
            .UseInMemoryDatabase(databaseName: "Test")));
    }

    [Fact]
    public void MsSqlTest()
    {
        Assert.True(Test(new DbContextOptionsBuilder<TestContext>()
            .UseSqlServer("Data Source=.;MultipleActiveResultSets=True;Integrated Security=True")));
    }

    private static bool Test(DbContextOptionsBuilder<TestContext> builder)
    {
        var options = builder.UseLazyLoadingProxies().Options;
        using (var ctx = new TestContext(options))
        {
            ctx.TestEntities.RemoveRange(ctx.TestEntities.ToArray());
            ctx.TestEntities.Add(new TestEntity());
            ctx.SaveChanges();
        }

        using (var ctx = new TestContext(options))
        {
            var e = ctx.TestEntities.Single();
            e.TestOwnedEntity.Code = "test";
            return ctx.ChangeTracker.Entries().Any(o => o.State != EntityState.Unchanged);
        }
    }
}

public class TestContext : DbContext
{
    public TestContext() : base(new DbContextOptionsBuilder<TestContext>()
        .UseSqlServer("Data Source=.;MultipleActiveResultSets=True;Integrated Security=True")
        .UseLazyLoadingProxies()
        .Options)
    {
    }

    public TestContext(DbContextOptions options) : base(options)
    {
    }

    public DbSet<TestEntity> TestEntities { get; set; }
}

public class TestEntity
{
    public long Id { get; set; }
    public virtual TestOwnedEntity TestOwnedEntity { get; private set; } = new TestOwnedEntity();
}

[Owned]
public class TestOwnedEntity
{
    public string Code { get; set; }
}

在此示例中,上下文应检测到更改。 “在内存数据库中”可以正确检测到它,但是MS Sql提供程序无法检测到它。这很可能是由于缺少拥有类型周围的代理引起的。当拥有类型的所有属性均为默认属性且未初始化时,所拥有实体为null时,缺少代理。

您能给我一些提示以正确设置它吗?我不想删除拥有实体的默认初始化,这将迫使我们检查所有地方是否拥有实体为null。

c# .net ef-core-3.1
1个回答
0
投票

我相信您必须为Equals实现方法TestOwnedEntity,类似:

public override bool Equals(object obj)
{
    var other = obj as TestOwnedEntity;
    if (other == null) return false;
    if (object.ReferenceEquals(this, obj) return true;
    return other.Code == this.Code;
}
© www.soinside.com 2019 - 2024. All rights reserved.