Entity framework 有关系的种子项目

Entity framework 有关系的种子项目,entity-framework,entity-framework-6,Entity Framework,Entity Framework 6,考虑以下几点: public class Foo { [Key] public int Id { get; set; } public string Name { get; set; } public string Something { get; set; } public virtual ICollection<Bar> Bars { get; set; } } public class Bar { [Key] pu

考虑以下几点:

public class Foo
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public string Something { get; set; }

    public virtual ICollection<Bar> Bars { get; set; }
}

public class Bar
{
    [Key]
    public int Id { get; set; }

    public string Name { get; set; }

    public string Something { get; set; }

    [ForeignKey("Foo")]
    public int FooId { get; set; }
    public virtual Foo Foo { get; set; }
}
如果我运行
updatedatabase
所有操作都如您所期望的那样工作,并且我会为每个
Foo
添加相关的

现在,如果我将种子数据更改为:

context.Foos.AddOrUpdate(
    r => r.Name,
    new Foo
    {
        Name = "Foo 1",
        Something = "BlahBlahBlah",
        Bars = new List<Bar>
        {
            new Bar { Name = "Foo 1 Bar 1", Something = "BlahBlahBlah" },
            new Bar { Name = "Foo 1 Bar 2", Something = "BlahBlahBlah" },
            new Bar { Name = "Foo 1 Bar 3", Something = "BlahBlahBlah" },
        }
    },
    ...

但考虑到我使用标识列作为键,我无法知道要将哪个
Bar
s添加到哪个
Foo
s。有什么想法吗?

当我输入问题时,我突然想到我可以这样做:

var bar1 = new Bar { Name = "Foo 1 Bar 1", Something = "Blah" };
var bar2 = new Bar { Name = "Foo 1 Bar 2", Something = "Blah" };
var bar3 = new Bar { Name = "Foo 1 Bar 3", Something = "Blah" };
...

context.Bars.AddOrUpdate(
    r => r.Name,
    bar1,
    bar2,
    bar3,
    ...
);

context.Foos.AddOrUpdate(
    r => r.Name,
    new Foo
    {
        Name = "Foo 1",
        Something = "Blah",
        Bars = new List<Bar>
        {
            bar1,
            bar2,
            bar3
        }
    },
    ...
);
var bar1=newbar{Name=“Foo 1 Bar 1”,Something=“Blah”};
var bar2=newbar{Name=“Foo 1 Bar 2”,Something=“Blah”};
var bar3=newbar{Name=“Foo 1 Bar 3”,Something=“Blah”};
...
context.bar.AddOrUpdate(
r=>r.Name,
bar1,
bar2,
bar3,
...
);
context.Foos.AddOrUpdate(
r=>r.Name,
新富
{
Name=“Foo 1”,
某物=“诸如此类”,
条=新列表
{
bar1,
bar2,
三维直方图
}
},
...
);
然而,我还没有机会对此进行测试,无论如何,我仍然愿意接受其他想法。

您的第一种方法(问题)和第二种方法(答案)都不适用于第二次执行种子方法

第一种方法

Bars = new List<Bar>
{
    new Bar { Name = "Foo 1 Bar 1", Something = "Blah" },
    // new Bar { Name = "Foo 1 Bar 4", Something = "Blah" },
}
var bar1 = new Bar { Name = "Foo 1 Bar 1", Something = "Blah" };
context.Bars.AddOrUpdate(
    r => r.Name,
    bar1
);
context.Foos.AddOrUpdate(
    r => r.Name,
    new Foo
    {
        Name = "Foo 1",
        Something = "Blah",
        Bars = new List<Bar>
        {
            bar1
        }
    }
);
这比第一个方法更糟糕,Seed方法的第二次执行将抛出异常,因为在更新任何
时,它将尝试更新
与未找到
Foo
的关系,未指定
条的FooId
,这意味着其值将为0<找不到Id等于0的code>Foo

解决方案

您需要定义临时密钥才能正确执行“添加或更新”

var bar1 = 
    new Bar { Id = 1, Name = "Foo 1 Bar 1", Something = "Blah", FooId = 1 };
var bar2 = 
    new Bar { Id = 2, Name = "Foo 1 Bar 2", Something = "Blah", FooId = 1 };
var bar3 = 
    new Bar { Id = 3, Name = "Foo 1 Bar 3", Something = "Blah", FooId = 1 };
// var bar4 =
//     new Bar { Id = 4, Name = "Foo 1 Bar 4", Something = "Blah", FooId = 1 };

db.Bars.AddOrUpdate(
    r => r.Name,
    bar1,
    bar2,
    bar3
    // bar4
);

db.Foos.AddOrUpdate(
    r => r.Name,
    new Foo
    {
        Id = 1,
        Name = "Foo 1",
        Something = "Blah"
    }
);
第二次执行Seed方法将把
foo's和bar'Something
更新为
BlahBlahBlah
。新的
(注释代码)将成功添加并引用现有的
Foo

更多

var bar1 = new Bar { Name = "Foo 1 Bar 1", Something = "Blah" };
context.Bars.AddOrUpdate(
    r => r.Name,
    bar1
);
context.Foos.AddOrUpdate(
    r => r.Name,
    new Foo
    {
        Name = "Foo 1",
        Something = "Blah",
        Bars = new List<Bar>
        {
            bar1
        }
    }
);
var bar1 = 
    new Bar { Id = 1, Name = "Foo 1 Bar 1", Something = "Blah", FooId = 1 };
var bar2 = 
    new Bar { Id = 2, Name = "Foo 1 Bar 2", Something = "Blah", FooId = 1 };
var bar3 = 
    new Bar { Id = 3, Name = "Foo 1 Bar 3", Something = "Blah", FooId = 1 };
// var bar4 =
//     new Bar { Id = 4, Name = "Foo 1 Bar 4", Something = "Blah", FooId = 1 };

db.Bars.AddOrUpdate(
    r => r.Name,
    bar1,
    bar2,
    bar3
    // bar4
);

db.Foos.AddOrUpdate(
    r => r.Name,
    new Foo
    {
        Id = 1,
        Name = "Foo 1",
        Something = "Blah"
    }
);