【问题标题】:EF6 Seed method dropping referencesEF6 种子方法删除引用
【发布时间】:2018-10-26 16:49:16
【问题描述】:

我首先使用 EF6 代码,并尝试在种子方法中添加一些测试数据。我正在使用一个自引用的对象。该引用是可选的,因此顶级元素的 ParentOrgId 为空。 OrgId 是一个身份列,所以我不为其设置 ID。我第一次运行 update-database 时,对象被正确添加并且 ParentOrgId 是正确的。第二次和任何后续时间,我运行 update-database 所有 ParentOrgIds 都更改为 null。我必须从数据库中删除条目,然后它会第一次工作,然后第二次将它们更改为空。知道为什么要删除引用吗?

对象:

public class Org
    {
        public int OrgId { get; set; }
        public int? ParentOrgId { get; set; }
        public string Name { get; set; }
        public int Depth { get; set; }

        public virtual Org ParentOrg { get; set; }
        public virtual ICollection<Org> Children { get; set; }
    }

配置:

public OrgConfiguration()
    {
        HasKey<int>(o => o.OrgId);

        HasOptional<Org>(o => o.ParentOrg)
            .WithMany(o => o.Children)
            .HasForeignKey(o => o.ParentOrgId);
    }

在种子方法中:

        Org[] seedOrgs = new Org[4];
        Org o1 = new Org();
        o1.Name = "TEST";
        o1.Depth = 0;
        seedOrgs[0] = o1;

        Org o2 = new Org();
        o2.Name = "TESTC1";
        o2.Depth = 1;
        o2.ParentOrg = o1;

        seedOrgs[1] = o2;

        Org o3 = new Org();
        o3.Name = "TESTC11";
        o3.Depth = 2;
        o3.ParentOrg = o2;
        seedOrgs[2] = o3;

        Org o4 = new Org();
        o4.Name = "TESTC2";
        o4.Depth = 1;
        o4.ParentOrg = o1;
        seedOrgs[3] = o4;

        context.Orgs.AddOrUpdate(o => o.Name, seedOrgs);

【问题讨论】:

    标签: entity-framework entity-framework-6


    【解决方案1】:

    这可能是由于known bug 中的AddOrUpdate

    对匹配的实体执行查询,如果存在,将返回一个新的实体实例。 (...) 传递给 AddOrUpdate 方法的实例基本上被丢弃了。但是,应用程序代码仍在使用这个丢弃的实例,这导致了在这个 bug 中出现的那种意外行为。

    我会试试这个:

    Org o1 = new Org();
    o1.Name = "TEST";
    o1.Depth = 0;
    context.Orgs.AddOrUpdate(o => o.Name, o1);
    o1 = context.Orgs.Local.Single(o => o.Name == o1.Name);
    

    然后不要添加 o1seedOrgs 并执行其余代码。

    顺便说一句,你也可以这样做

    context.Orgs.AddOrUpdate(o => o.Name, o2, o3, o4);
    

    【讨论】:

    • 我认为您可能遇到了该错误,但即使进行了这些更改,引用仍然会被丢弃在第二个更新数据库中。
    【解决方案2】:

    如果您使用 Seed() 方法插入数据,最好让包含 Seed() 方法的类(通常是 Configuration)继承自:

    DropCreateDatabaseAlways<YourContext>
    

    这样,您的数据库将在每次启动程序时被删除并重新创建,因此您每次都会获得新的所需数据。

    【讨论】:

    • 有时我想保留里面的东西。并非所有数据都使用种子方法输入。
    猜你喜欢
    • 2017-09-11
    • 2014-03-02
    • 1970-01-01
    • 2017-06-10
    • 2015-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    相关资源
    最近更新 更多