0

我正在尝试在与实体之间建立可选关系,但我无法找到正确的语法。实际上我需要一个 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,永远不会更多。一个 Bar 可以有一个 LeftFoo 和一个 RightFoo,或者一个或一个都没有。如果 Foo 的 Bar 属性没有被 Bar 引用,则它应该为 null,并且它应该包含在被 Bar 引用时引用它的 Bar。

上面的代码 Bar 正确引用了 Foo,但 EF 为 Foo 表提供了 Bar_Id 并且 Bar 属性始终为空。

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

4

3 回答 3

1

尝试这个:

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"));
    ...
}

结果

表格截图

编辑播种

我会做以下事情,没有测试代码,但它应该可以工作:

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();

为简单起见barsleftFoos并且rightFoos具有相同数量的元素。

于 2013-07-23T13:35:19.577 回答
0

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

于 2015-02-24T13:50:27.297 回答
0

我修改了这样的代码:

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,至少从 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();

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

于 2013-07-24T14:40:03.290 回答