2012-11-03 66 views
1

我有一個代表我認爲可能是EF錯誤的代表。我想在兩個實體之間分割一張桌子。這些實體中的每一個都包含對第三個實體的引用。兩個引用必須使用相同的外鍵屬性名稱公開。由於它們映射到同一個表中的列,因此使用配置(或在此示例中爲屬性)使列名唯一。EF表分割:InvalidOperationException - 序列包含多個匹配元素

當我嘗試加載模型時,我從EF獲得上述異常。如果我修改其中一個FK屬性的名稱,則錯誤消失。

這是我的模型。代碼是可行的。要重現此問題,請將Foo2.Foo3Id1重命名爲Foo3Id,這是我需要的值。

爲什麼你想這樣做?

如果你想知道爲什麼我需要這兩個屬性具有相同的名稱,這裏的解釋。

我有一個包含多個地址(例如郵政地址和帳單地址)的表。這是一個現有的數據庫,所以我不能更改表結構。每個地址由一系列標準列表示。每列的名稱都有一個標識地址種類的前綴和一個標識地址部分的後綴,例如, BillingAddressLine1BillingAddressZipCodePostalAddressLine1

它會似乎使用複雜類型將處理此。但是,還有一個額外的複雜因素:每個地址包含引用Cities表的CityId。複雜類型don't support relationships and navigation properties。所以我想要的解決方案是使用表拆分來代替,並將每組地址屬性拆分爲它自己的實體。表示地址的每個實體都來自基本類型,例如Address或者實現接口IAddress

隨着表格拆分,我小心地觀察幾種類型映射到同一個表的限制,they must all have navigation properties to each other

在下面的代碼中,Foo1Foo2都是地址類型(並且會實現一些通用接口)。 Foo3City。這是我能想出的最簡單的問題。

代碼示例

class Program 
{ 
    static void Main(string[] args) 
    { 
     // Use NuGet to import EF 5 into the project. 
     // This code is just enough to cause the metadata to be loaded and therefore demo the error. 
     using (Context cx = new Context()) 
     { 
      var qq = from f in cx.Foo3s 
        where f.Foo1s.Any() 
        select f; 
     } 
    } 
} 

[Table("Foo")] 
public class Foo1 
{ 
    [Key] 
    public virtual int Id { get; set; } 

    [Required] 
    public virtual Foo2 Foo2 { get; set; } 

    [ForeignKey("Foo3")] 
    [Column("Foo1_Foo3Id")] 
    public virtual int? Foo3Id { get; set; } 

    public virtual Foo3 Foo3 { get; set; } 
} 

[Table("Foo")] 
public class Foo2 
{ 
    [Key] 
    public virtual int Id { get; set; } 

    [Required] 
    public virtual Foo1 Foo1 { get; set; } 

    // Re-name the following property to Foo3Id (rather than Foo3Id1) and the model won't load. 
    // You get "InvalidOperationException: Sequence contains more than one matching element." 
    [ForeignKey("Foo3")] 
    [Column("Foo2_Foo3Id")] 
    public virtual int? Foo3Id1 { get; set; } 

    public virtual Foo3 Foo3 { get; set; } 
} 

[Table("Foo3")] 
public class Foo3 
{ 
    [Key] 
    public virtual int Id { get; set; } 

    [InverseProperty("Foo3")] 
    public virtual ICollection<Foo1> Foo1s { get; set; } 

    [InverseProperty("Foo3")] 
    public virtual ICollection<Foo2> Foo2s { get; set; } 
} 

public class Context : DbContext 
{ 
    public DbSet<Foo3> Foo3s { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     // Don't think we can configure 1:1 relationship using just attributes. 
     var foo2 = modelBuilder.Entity<Foo2>(); 
     foo2.HasRequired(q => q.Foo1) 
      .WithRequiredPrincipal(q => q.Foo2); 
    } 
} 

這是一個錯誤?難道我做錯了什麼?這是一個已知的EF限制嗎?

+0

你能報告http://entityframework.codeplex.com這個?我不知道這是否支持,但如果不是,那麼你應該得到一個更好的例外 – Pawel

+0

@Pawel - 謝謝。我創建了http://entityframework.codeplex.com/workitem/643並在這裏添加了一些關於爲什麼我要這樣做的更多信息。沒有那個背景信息,這聽起來有點模糊。 – Olly

+0

Brice找到了一個可以使用的解決方法,直到它解決 - 他將其發佈到codeplex站點上。以防萬一:「更改其中一個屬性名稱是一個有效的解決方法,直到它得到解決。」 – Pawel

回答

相關問題