2013-06-03 119 views
3

時正確的方法來設置外鍵關聯有兩個表在我的數據庫:MastersDetails
這些表都與一個一對多與外鍵約束,其中的Masters是主鍵表,Details是一個外鍵表。使用繼承

我想用繼承在我的模型都從Masters表單位:

abstract class Master 
{ 
    public int Id { get; set; } 
} 

class Master_1 : Master 
{ 
    // other properties 
} 

class Master_2: Master 
{ 
    // other properties 
} 

,並從Details表單位:

abstract class Detail 
{ 
    public int Id { get; set; } 
} 

class Detail_1 : Detail 
{ 
    // other properties 
} 

class Detail_2: Detail 
{ 
    // other properties 
} 

class Detail_3: Detail 
{ 
    // other properties 
} 

但對國外的關鍵是什麼?
從概念上講,Master_1只應包含Detail_1的詳細信息,而Master_2應包含Detail_2Detail_3的詳細信息。

如果我會從實體框架抽象的,我要補充的中間基類Detail_2Detail_3

abstract class Detail_2_Or_3 : Detail {} 
    class Detail_2 : Detail_2_Or_3 {} 
    class Detail_3 : Detail_2_Or_3 {} 

,讓我Master通用:

abstract class Master<TDetail> 
    where TDetail : Detail 
{ 
    public int Id { get; set; } 
    public Collection<TDetail> Details { get; private set; } 
} 

class Master_1 : Master<Detail_1> {} 
class Master_2 : Master<Detail_2_Or_3> {} 

但是如何可以做到這一點使用實體框架?我不喜歡這個解決方案,因爲Master的集合是Details,因爲這不能提供編譯時的保證。

我正在尋找沒有附加層的方式,而不是MasterDetail層次結構。 任何想法?

+0

這是一個有趣的閱讀,並希望爲您提供回味無窮...... http://weblogs.asp.net/manavi/archive/2011/01/ 03/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-3-table-per-concrete-type-tpc-and-selecting-strategy-guidelines.aspx –

+0

@PaulZahra: t認爲TPC繼承的描述可能有所幫助。可能是我錯過了什麼? – Dennis

+0

你看過TPT和TPH嗎? –

回答

0

這只是一個想法,我也不能與EF嘗試過了充分的,但是...

爲什麼不能做一些事情,就像你說的,並提供編譯時安全性與限制性集公共方法對你的域對象?

也就是說,Master在EF中設置了一個Details集合,但是您只能將Detail_1的一個實例添加到Master_1的一個實例等。然後您可以有一個方法返回一個強類型集合,該集合適合於基類型也是如此。

下面是代碼:

public abstract class Master<TDetail> where TDetail : Detail 
{ 
    public int Id { get; set; } 
    public List<Detail> Details { get; private set; } 

    public abstract void AddDetail(TDetail detail); 
    public abstract List<TDetail> GetDetails(); 
} 

public class Master_1 : Master<Detail_1> 
{ 
    public override void AddDetail(Detail_1 detail) 
    { 
     Details.Add(detail); 
    } 

    public override List<Detail_1> GetDetails() 
    { 
     return Details.Select(d => (Detail_1)d).ToList(); 
    } 
} 

public class Master_2 : Master<Detail_2_Or_3> 
{ 
    public override void AddDetail(Detail_2_Or_3 detail) 
    { 
     Details.Add(detail); 
    } 

    public override List<Detail_2_Or_3> GetDetails() 
    { 
     return Details.Select(d => (Detail_2_Or_3)d).ToList(); 
    } 
} 

public abstract class Detail 
{ 
    public int Id { get; set; } 

    //Foriegn Key 
    public int MasterId { get; private set;} 
} 

public class Detail_1 : Detail { } 

public abstract class Detail_2_Or_3 : Detail { } 
public class Detail_2 : Detail_2_Or_3 { } 
public class Detail_3 : Detail_2_Or_3 { }