2013-12-13 48 views
1

我已經花了幾個小時試圖谷歌這個答案,但我什麼也沒有提出。我希望這只是我不知道如何說明這一點而不是技術限制。我正在使用實體框架Code-First(v5),我試圖創建一個模型,它有兩個導航屬性共享一個外鍵。很明顯,這個外鍵不能存在於數據庫中,因爲它不能指向兩個子表。英孚能夠解決這個問題,仍然找出我想要使用自定義映射或註釋?實體框架 - 兩個導航屬性,一個鍵?

例子:

public class Parent { 
    public int Id { get; set; } 
    public string EntityType { get; set; } 
    public int EntityId { get; set; } 
    // Additional properties 

    [SomeSortOfAttributeICanPutHereToIndicateThisShouldUse("EntityId")] //? 
    public virtual Child1 { get; } 
    [SomeSortOfAttributeICanPutHereToIndicateThisShouldUse("EntityId")] //? 
    public virtual Child2 { get; } 
} 

public class Child1 { 
    public int Id { get; set; } 
    public string Prop1 { get; set; } 
} 

public class Child2 { 
    public int Id { get; set; } 
    public string Prop2 { get; set; } 
} 

public Database : DbContext { 
    public DbSet<Parent> Parents { get; set; } 
    public DbSet<Child1> Children1 { get; set; } 
    public DbSet<Child2> Children2 { get; set; } 
} 

var db = new Database(); 
var child1prop = db.Parents.First(p => p.EntityType == "Child1").Child1.Prop1; 
var child2prop = db.Parents.First(p => p.EntityType == "Child2").Child2.Prop2; 

正是我試圖做甚至有可能與實體框架,還是我浪費我的時間?

+0

我認爲你正在尋找的是一個表類型(TPT)的繼承。在這裏閱讀更多關於它:http://weblogs.asp.net/manavi/archive/2010/12/28/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2-table- per-type-tpt.aspx 編輯:我會詳細說明。如果你的Child1對象和你的Child2對象有相同的外鍵,我猜他們應該有相同的基類(我們稱之爲ChildBase)。如果你讓Parent的Child屬性爲ChildBase類型,你應該擁有你想要的東西 – Gabe

+0

'Child1'和'Child2'有很多相似之處嗎?或者,從一個基類中派生出來會有意義嗎? –

回答

0

我認爲這是不可能的。這聽起來像試圖設置從parent.cid到child1.cid和從parent.cid到child2.cid的FK約束。

我只是測試:這似乎是可能的(!!#!):

CREATE TABLE [dbo].[parent](
    [pid] [int] NOT NULL, 
    [cid] [int] NULL, 
CONSTRAINT [PK_parent] PRIMARY KEY CLUSTERED 
(
    [pid] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[parent] WITH CHECK ADD CONSTRAINT [FK_parent_child1] FOREIGN KEY([cid]) 
REFERENCES [dbo].[child1] ([cid]) 
GO 

ALTER TABLE [dbo].[parent] CHECK CONSTRAINT [FK_parent_child1] 
GO 

ALTER TABLE [dbo].[parent] WITH CHECK ADD CONSTRAINT [FK_parent_child2] FOREIGN KEY([cid]) 
REFERENCES [dbo].[child2] ([cid]) 
GO 

ALTER TABLE [dbo].[parent] CHECK CONSTRAINT [FK_parent_child2] 
GO 

但是:

這意味着,當你設置一個值,parent.cid你必須有一個在child1和child2中都行。

Imho,這會導致精神分裂症。

面對同樣的問題,我辭職了有兩個FKs。

另一種選擇是繼承:

class base { 
    int id {get; set;} 
} 

class child1 : base { 
} 

class child2 : base { 
} 

,然後再配置TPT。這將導致child1和child2的三張表。

在你的父母中,你可以擁有一個base類型的屬性。然後由您來處理這個屬性爲child1或child2。

希望這有助於

0

我會想象一個更好的方式來處理這將是有一個孩子在父實體的集合?這是一個簡單的1對多關係。

父類將包含一個孩子的集合,孩子將有一個對其父母的引用,那麼父母可以有x個孩子,而不是隻有兩個。

public class Parent { 
    public int Id { get; set; } 
    // Additional properties 

    public virtual List<Child> Children { get; set; } 
} 

public class Child { 
    public int Id { get; set; } 
    public string Prop1 { get; set; } 

    public int ParentId { get; set; } 
    public Parent Parent { get; set; } 
} 

public Database : DbContext { 
    public DbSet<Parent> Parents { get; set; } 
    public DbSet<Child> Children { get; set; } 
} 
+0

這並不能真正幫助我,因爲孩子的類型完全不同,我不能讓他們通過繼承來共享一個共同的祖先。 –

+0

在這種情況下他們應該沒有不同的表格嗎? – BenjaminPaul