1

這是我製作的示例應用程序,它產生與我的實際更復雜的應用程序相同的行爲。 我很明顯在某處丟失了一些配置方面,但無法弄清楚我的生活。出於某種原因,我的KID類中的每個集合都在Sweet table中接收它自己的字段和外鍵....只要我不能看到....., 如何阻止EF生成這些?EF5 TPH正在生成額外的外鍵 - 如何擺脫它們?

實施例類,配置和所得遷移代碼如下(NB,如果我使用TPT代替TPH的額外字段不添加和OWNERID用作關係字段就好)

我的類:

public class Sweet 
    { 
     [Key] 
     public int SweetId { get; set; } 
     public string SweetName { get; set; } 

     [ForeignKey("OwnerId")] 
     public Kid Owner { get; set; } 
     public int OwnerId { get; set; } 
    } 
    public class Chocolate : Sweet {} 
    public class HardBoiled : Sweet {} 
    public class Chewy : Sweet {} 

    public class Kid 
    { 
     public int KidId { get; set; } 
     public string FirstName { get; set; } 
     public virtual ICollection<Chocolate> Chocolates { get; set; } 
     public virtual ICollection<HardBoiled> BaggedSweeets { get; set; } 
     public virtual ICollection<Chewy> PacketSweets { get; set; } 
    } 

我的配置(從OnModelCreating調用)

public class SweetConfiguration : EntityTypeConfiguration<Sweet> 
{ 
    public SweetConfiguration() 
    { 
     Map(m => m.ToTable("Sweet")); 

     Map<Chocolate>(i => i.Requires("SweetType").HasValue(1)); 

     Map<Chewy>(i => i.Requires("SweetType").HasValue(2)); 

     Map<HardBoiled>(f => f.Requires("SweetType").HasValue(3)); 
    } 
} 

生成遷移代碼:

public override void Up() 
    { 
     CreateTable(
      "dbo.Kid", 
      c => new 
       { 
        KidId = c.Int(nullable: false, identity: true), 
        FirstName = c.String(), 
       }) 
      .PrimaryKey(t => t.KidId); 

     CreateTable(
      "dbo.Sweet", 
      c => new 
       { 
        SweetId = c.Int(nullable: false, identity: true), 
        SweetName = c.String(), 
        OwnerId = c.Int(nullable: false), 
        Kid_KidId = c.Int(), <--- DON'T NEED THIS 
        Kid_KidId1 = c.Int(), <--- OR THIS 
        Kid_KidId2 = c.Int(), <-- OR THIS! 
        SweetType = c.Int(), 
       }) 
      .PrimaryKey(t => t.SweetId) 
      .ForeignKey("dbo.Kid", t => t.Kid_KidId) <!-- LIKEWISE FOR THESE THREE KEYS 
      .ForeignKey("dbo.Kid", t => t.Kid_KidId1) 
      .ForeignKey("dbo.Kid", t => t.Kid_KidId2) 
      .ForeignKey("dbo.Kid", t => t.OwnerId, cascadeDelete: true) 
      .Index(t => t.Kid_KidId) 
      .Index(t => t.Kid_KidId1) 
      .Index(t => t.Kid_KidId2) 
      .Index(t => t.OwnerId); 

    } 

UPDATE:

因爲這似乎是不支持我目前的模型我已經改變了我的孩子類是這樣的:

public class Kid 
{ 
    public int KidId { get; set; } 
    public string FirstName { get; set; } 
    public virtual ICollection<Sweet> Sweets { get; set; } 

    [NotMapped] 
    public ICollection<HardBoiled> BaggedSweets 
    { 
     get 
     { 
      return Sweets.OfType<HardBoiled>().ToList(); 
     } 
    } 
    ... and two more read-only NotMapped properties for the other collections... 
} 

回答

1

您不能在這個模型中使用三個集合。 EF預計,反向屬性和FK屬性(OwnerOwnerId)的在集合指的類聲明直接(即在ChocolateHardBoiledChewy)在基類和不。爲了使它工作,只有一個外鍵,你只能在Kid是指基類中定義一個導航集合,其中OwnerOwnerId中宣稱:

public class Kid 
{ 
    public int KidId { get; set; } 
    public string FirstName { get; set; } 
    public virtual ICollection<Sweet> Sweets { get; set; } 
} 

(您可以順便說一句提取特定類型的此集合使用Sweets.OfType<Chocolate>()等)

這也是TPT的情況。您的TPT測試中是否可能沒有SweetConfigurationDbSet<Sweet>?這會導致模型根本沒有繼承(來自EF視角),因爲基類Sweet的所有屬性都將被添加到三個子表中。

+0

在我的實際代碼中,Sweet是一個抽象類,所以我沒有在任何地方使用它 - 但是我看到了你的觀點,即沒有繼承。 這個問題EF具體嗎?其他ORM可以應付這種類型的模型嗎? –

+0

@DaveR:我不知道其他ORM是否可以映射這些類,就像你想映射它們一樣。在我看來,使用單個「Sweets」集合並不是一個很大的損失,因爲您始終可以將子類從集合中篩選出來。如果你想在'Kid'中添加三個額外的(未映射的)只讀屬性(只有一個getter),那麼返回'Sweets.OfType ()'爲'IEnumerable '等 – Slauma

+0

是的。已經編輯我的答案,以顯示我是如何做到這一點的。感謝澄清。 –

相關問題