如何使用Fluent API以一对一或一对一的关系正确映射外键?

时间:2013-10-16 21:55:31

标签: entity-framework entity-framework-5

我有以下实体:

public class Foo
{
  public int MyId1 { get; set; }
  public int MyId2 { get; set; }
  public int MyId3 { get; set; }
  public Bar Bar { get; set; }
}

public class Bar
{
  public int MyId1 { get; set; }
  public int YourId2 { get; set; }
  public int MyId3 { get; set; }
  public Foo Foo { get; set; }
}

和映射:

// Foo Mapping
this.HasKey(t => new { t.MyId1, t.MyId2, t.MyId3 });
this.Property(t => t.MyId1).HasColumnName("my_id1");
this.Property(t => t.MyId2).HasColumnName("my_id2");
this.Property(t => t.MyId3).HasColumnName("my_id3");

// Bar Mapping
this.HasKey(t => new { t.MyId1, t.MyId3, t.YourId2 }); // Notice different order
this.Property(t => t.MyId1).HasColumnName("my_id1");
this.Property(t => t.YourId2).HasColumnName("your_id2");
this.Property(t => t.MyId3).HasColumnName("my_id3");
this.HasRequired(t => t.Foo)
  .WithOptional(t => t.Bar);

当我对Foo进行选择时,生成的sql查询看起来像这样:

select *
from Foo foo
left outer join Bar bar
  on foo.my_id1 = bar.Foo_MyId1 
    and foo.my_id2 = bar.Foo_MyId2 
    and foo.my_id3 = bar.Foo_MyId3

这显然给了我SQL错误。我猜这是因为它试图从关系中推断出外键列。所以我尝试在映射中指定实际的FK列名称:

this.HasRequired(t => t.Foo)
  .WithOptional(t => t.Bar)
  .Map(m =>
    {
      m.MapKey("my_id1", "your_id2", "my_id3");
    }
  );

但是这给了我以下错误:

Unhandled Exception: System.Data.Entity.ModelConfiguration.ModelValidationException:
One or more validation errors were detected during model generation:

my_id1: Name: Each property name in a type must be unique. Property name 'my_id1' is already defined.
your_id2: Name: Each property name in a type must be unique. Property name 'your_id2' is already defined.
my_id3: Name: Each property name in a type must be unique. Property name 'my_id3' is already defined.

知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

.Map(...)用于在未在POCO中定义外键时指定外键的名称。在您的情况下,您在POCO中定义代表FK的属性,以便您获得此重复名称错误。

我无法确定如何执行您所要求的操作(使用流畅的api为一对一关系指定FK字段)但可以使用{{1来使用数据注释来完成属性