Ef code first EF代码第一个0..1到0..1关系

Ef code first EF代码第一个0..1到0..1关系,ef-code-first,entity-framework-5,Ef Code First,Entity Framework 5,我试图在to实体之间建立可选关系,但在找到正确的语法时遇到了困难。实际上,我需要一个0..1到0..2的关系,但我猜一旦我找到了实现0..1到0..1的方法,这将是微不足道的 我得到的是: class Foo { int Id { get; set; } //navigation property virtual Bar Bar { get; private set; } } class Bar { int Id { get; set; } int?

我试图在to实体之间建立可选关系,但在找到正确的语法时遇到了困难。实际上,我需要一个0..1到0..2的关系,但我猜一旦我找到了实现0..1到0..1的方法,这将是微不足道的

我得到的是:

class Foo
{
    int Id { get; set; }
    //navigation property
    virtual Bar Bar { get; private set; }
}

class Bar
{
    int Id { get; set; }

    int? LeftFooId { get; set; }
    [ForeignKey("LeftFooId")]
    Foo LeftFoo { get; set; }

    int? RightFooId{ get; set; } 
    [ForeignKey("RightFooId")]
    Foo RightFoo { get; set; }
}
一个Foo可以连接到零或一个Bar,不能再连接更多。酒吧可以有LeftFoo和RightFoo,也可以一个或两个都没有。如果Foo的Bar属性没有被Bar引用,那么它应该为null,并且它应该包含被Bar引用时引用它的Bar

对于上面的代码,Bar正确地引用了Foo,但是EF为Foo表提供了Bar_Id,并且Bar属性始终为null

我尝试了几种不同的方法来设置这些实体类,并使用了不同的Fluent API调用来实现这一点,但没有得到想要的结果。

尝试以下方法:

public class Foo
{
    public int Id { get; set; }
    public virtual Bar Bar { get; set; }
}

public class Bar
{
    public int Id {get; set;}
    public virtual Foo LeftFoo {get;set;}
    public virtual Foo RightFoo {get;set;}
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Bar>()
                .HasOptiona(b => b.LeftFoo)
                .WithOptionalDependent()
                .Map(k = k.MapKey("LeftFooId"));

    modelBuilder.Entity<Bar>()
                .HasOptional(b => b.RightFoo)
                .WithOptionalDependent()
                .Map(k => k.MapKey("RightFooId"));
    ...
}
公共类Foo
{
公共int Id{get;set;}
公共虚拟条{get;set;}
}
公共类酒吧
{
公共int Id{get;set;}
公共虚拟Foo LeftFoo{get;set;}
公共虚拟Foo RightFoo{get;set;}
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.haoptiona(b=>b.LeftFoo)
.WithOptionalDependent()
.Map(k=k.MapKey(“LeftFooId”);
modelBuilder.Entity()
.has可选(b=>b.RightFoo)
.WithOptionalDependent()
.Map(k=>k.MapKey(“RightFooId”);
...
}
结果

编辑种子设定

我将执行以下操作,没有测试代码,但它应该可以工作:

var bars = new List<Bar>();
   bars.Add(new Bar());
   bars.Add(new Bar());
...//this means as many as you need/want
   bars.ForEach(b => context.Bars.AddOrUpdate(b));
context.SaveChanges();

var leftFoos = new List<Foo>();
   leftFoos.Add(new Foo());
   leftFoos.Add(new Foo());
...//this means as many as you need/want
   leftFoos.ForEach(f => context.Foos.AddOrUpdate(f));
context.SaveChanges();

var rightFoos = new List<Foo>();
   rightFoos.Add(new Foo());
   rightFoos.Add(new Foo());
...//this means as many as you need/want
   rightFoos.Foreach(f => context.Foos.AddOrUpdate(f));
context.SaveChanges();

int i=0;
foreach(var bar in bars)
{
   bar.LeftFoo = leftFoos.ElementAt(i);
   bar.RightFoo = rightFoos.ElementAt(i);
   i++;
}
context.SaveChanges();
var bar=新列表();
添加(新条());
添加(新条());
…//这意味着你需要/想要多少就有多少
bars.ForEach(b=>context.bars.AddOrUpdate(b));
SaveChanges();
var leftFoos=新列表();
添加(newfoo());
添加(newfoo());
…//这意味着你需要/想要多少就有多少
ForEach(f=>context.Foos.AddOrUpdate(f));
SaveChanges();
var rightFoos=新列表();
Add(newfoo());
Add(newfoo());
…//这意味着你需要/想要多少就有多少
Foreach(f=>context.Foos.AddOrUpdate(f));
SaveChanges();
int i=0;
foreach(以条为单位的变量条)
{
bar.LeftFoo=leftFoos.ElementAt(i);
bar.RightFoo=rightFoos.ElementAt(i);
i++;
}
SaveChanges();

为简单起见,
左foos
右foos
具有相同数量的元素。

我修改了如下代码:

class Foo
{
    int Id { get; set; }
    int? BarId { get; set; }
    [ForeignKey("BarId")]
    virtual Bar Bar { get; set; }
}

class Bar
{
    int Id { get; set; }

    int? LeftFooId { get; set; }
    [ForeignKey("LeftFooId")]
    Foo LeftFoo { get; set; }

    int? RightFooId{ get; set; } 
    [ForeignKey("RightFooId")]
    Foo RightFoo { get; set; }
}
我可能错了,但自动分配一对FK的my是不可能的,至少从Foo到Bar:EF如何知道应该将FK分配给LeftFoo还是RightFoo。所以现在我只是手动完成这两项任务:

Foo myFirstFoo = new Foo();
Foo mySecondFoo = new Foo();
Bar myBar = new Bar();
context.Add(myFirstFoo); context.Add(mySecondFoo); context.Add(myBar);
context.SaveChanges();
myFirstFoo.BarId = myBar.Id;
myBar.LeftFooId = myFirstFoo.Id;
mySecondFoo.BarId = myBar.Id;
myBar.RightFooId = mySecondFoo.Id;
context.Update(myFirstFoo); context.Update(mySecondFoo); context.Update(myBar);
context.SaveChanges();

这似乎很有效,但我确实希望可以做得更好。

尝试将您的属性虚拟化,并使用POCO代理(使用Create而不是new…)。这将确保侧属性的自动更新。i、 e当将一个Foo分配给一个Bar时,POCO代理将相应的Bar分配给该Foo,但是。。。这应该是主要的问题:如果给一个Foo分配一个条,你会期望什么?您希望自动分配哪个属性,从左到右?注释Bar属性[InverseProperty(“…”)以表明这一点,并考虑在Foo中可能需要另一个Bar类型的属性用于其他关系。
希望这对我有所帮助

这正是我所拥有的。FK在那里,但当我分配LeftFoo和RightFoo时,这些Foo的Bar_Id保持为空。我试图通过添加OptionalDependent(f=>f.Bar)来解决这个问题,但这给了我一个错误:指定的模式无效。错误:(85,6):错误0040:命名空间(别名=Self)中未定义类型Bar\u LeftFoo。是否确实没有执行其他操作?当我在本地测试时,它工作了。您如何将
分配给条形图?你能发布吗?我目前在Seed中所做的是使用所有fk的null创建一组条形图,然后保存更改,然后循环所有条形图,然后为每个空的leftfoo或rightfoo创建一个新的foo,将条形图属性保留为null,然后再进行另一次保存。然后我将新的foo分配给该条(bar.leftfoo=foo)。然后是更新和保存。