【问题标题】:EF7 setting child object to null issueEF7 将子对象设置为空问题
【发布时间】:2016-06-08 02:28:40
【问题描述】:

我在我的项目中使用 EF7 rc2。 有两个相关的类

public sealed class Member
{   
    ......   
    public MemberState State { get; set; }
}

public sealed class MemberState
{
    public Guid Id { get; set; }
    public Org Org { get; set; }
    ....
}

及EF配置:

modelBuilder.Entity<MemberState>(entity =>
{
    entity.ToTable("State");
    entity.HasKey(e => e.Id);    
    entity.Property<Guid>("Idf_Org");
    entity.HasOne(e => e.Org).WithMany().HasForeignKey("Idf_Org");    
    .....    
});

modelBuilder.Entity<Member>(entity =>
{
    entity.HasKey(e => e.Id);
    entity.Property<Guid>("Idf_State");
    entity.HasOne(member => member.State).WithMany().HasForeignKey("Idf_State");
});

所以,在某些时候,我想将 null 设置为 MembersState 中的 Org 字段。

mwmbwe.State = new MemberState()
{
    Id = Guid.NewGuid(),
    ....
    Org = null
 };          
 _provider.SaveChanges();  

将更改保存到数据库时发生异常。 EF 尝试插入具有空 PK 的相关 Org 项目。 有什么办法可以避免吗?

还尝试通过直接 ExecuteSqlCommand 解决此问题,而不是从 EF 提供程序获取新的 MemberState,但它也会引发异常: “对象引用未设置为对象的实例。”

在数据库字段中,包含标记为“允许为空”的 Idf_Org

【问题讨论】:

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


    【解决方案1】:

    如果 MemberStateOrg 之间的关联是可选的,那么您需要在 fluent API 中指定:

    entity.HasOne(e => e.Org)
          .WithMany()
          .HasForeignKey("Idf_Org")
          .IsRequired(false);
    

    因此,EF Core 将允许您在运行时保存没有 Org 的 MemberState。

    【讨论】:

    • 实际上,我已经尝试过了,这似乎是一个正确的决定,但是重新配置后我的 ASP.NET core 1.0 应用程序无法启动。这很奇怪 - 没有异常,或者输出警告被触发
    • UPD 输出包含以下内容:抛出异常:Microsoft.EntityFrameworkCore.dll 中的“System.InvalidOperationException”
    【解决方案2】:

    魔鬼在细节)

    Mortezas 的回答非常有帮助,但是在应用它之后,我遇到了这个问题: Microsoft.EntityFrameworkCore.dll 中出现“System.InvalidOperationException”类型的异常,但未在用户代码中处理附加信息:实体类型“MemberState”上的外键 {'Idf_Org'} 不能标记为可选,因为它不包含任何可为空类型的属性。任何外键都可以标记为必需,但只有具有至少一个可为空类型的属性且不属于主键的外键才能标记为可选。

    所以,真正的决定是

    entity.Property<Guid?>("Idf_Org");
    entity.HasOne(e => e.Org).WithMany().HasForeignKey("Idf_Org").IsRequired(false);
    

    只有当影子属性也被标记为可空时才有效

    【讨论】:

    • 没错,另一种(更好的)方法是在映射到 Idf_OrgMemberState 对象上拥有一个可为空的 FK 属性,而不是遮蔽它。
    猜你喜欢
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 2010-11-25
    • 2012-06-17
    • 2015-05-25
    • 2015-02-16
    • 2019-05-15
    • 1970-01-01
    相关资源
    最近更新 更多