2013-03-23 44 views
1

我已經在我的領域類(簡體)以下如何創建可導航到多個實體類型的導航屬性?

public enum JobType 
{ 
    SalesOrder = 1, 
    StockOrder = 2 
} 
public class SalesOrder : LoggedEntity 
{ 
    public string Name { get; set; } // and other fields 


} 
public class StockOrder : LoggedEntity 
{ 
    public string Name { get; set; } // and other fields 


} 

public class Job : LoggedEntity 
{ 
    public int JobType { get; set; } // jobtype enum 
    public virtual LoggedEntity LinkedEntity { get; set; } 
} 

我的背景是如下:

public class Context : DbContext 
{ 
public DbSet<Job> Jobs { get; set; } 
public DbSet<StockOrder> StockOrders { get; set; } 
public DbSet<SalesOrder> SalesOrders { get; set; } 
} 

當我運行遷移我得到[1]所以,用一種抽象的存在好像不工作描述這裏]錯誤。

我的問題是,我如何創建一個導航屬性,可以導航到多個實體類型?

如果JobType = SalesOrder,那麼我想導航到銷售訂單,如果JobType = StockOrder,那麼我想導航到庫存訂單。

我想用一個表每層次結構戰略[見TPH這裏] [2]

+1

_I我想我正在使用一個表每Heirarchy Strategy_你的意思是說,所有的類都映射到一個表?我可以想象你用SalesOrder和StockOrder來做這件事,但是Job是一個完全不同的實體。也許你的問題更深入,即使用基類「LoggedEntity」。這大大地影響了你的繼承。 – 2013-03-23 22:45:53

+0

LoggedEntity實際上並不是一個表格。它是抽象的,所有在其中定義的字段都屬於每個表格。我想我可能需要探索爲StockOrder和SalesOrder添加一個不同的類以繼承 – 2013-03-23 22:58:20

+0

啊!正是我在做什麼,看到我的答案。 – 2013-03-23 23:09:59

回答

1

訣竅是讓EF忘記LoggedEntity類。根據這個例子重塑您的實體:

public enum JobType 
{ 
    SalesOrder = 1, 
    StockOrder = 2 
} 

public abstract class LoggedEntity 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } // and other fields 
} 

public abstract class BaseOrder : LoggedEntity // New base class for orders!! 
{ } 

public class SalesOrder : BaseOrder 
{ } 

public class StockOrder : BaseOrder 
{ } 

public class Job : LoggedEntity 
{ 
    public JobType JobType { get; set; } // jobtype enum 
    public virtual BaseOrder Order { get; set; } 
} 

public class Tph2Context : DbContext 
{ 
    public DbSet<Job> Jobs { get; set; } 
    public DbSet<BaseOrder> Orders { get; set; } 
} 

您將看到遷移創建兩個表,喬布斯和BaseOrders(有待提高的名字)。 Job現在有一個屬性Order,可以是SalesOrderStockOrder

您可以通過

contex.Orders.OfType<StockOrder>() 

查詢特定訂單類型和你會發現,EF不知道LoggedEntity,因爲

context.Set<LoggedEntity>() 

會拋出異常

實體LoggedEntity類型不是當前上下文模型的一部分。

0
how do I create a navigation property that can navigate 
to more than one entity type? 

你不能這樣做。至少不是現在。導航屬性是描述實體之間關係的方式。它們至多代表着某種sql關係。所以你不能即時改變或定義這種關係。你必須事先定義它。

現在,爲了做到這一點,你必須定義單獨的導航性能爲您的獨立條件,即

public class Job : LoggedEntity 
{ 
    public int JobTypeSales { get; set; } 
    public int JobTypeStock { get; set; } 

    public virtual SalesOrder SalesOrder { get; set; } 
    public virtual StockOrder StockOrder { get; set; } 
} 

然後通過流暢API在配置modelbuilder鏈接它們。

 HasRequired(s => s.SalesOrder) 
       .WithMany() 
       .HasForeignKey(s => s.JobTypeSales).WillCascadeOnDelete(true); 

    HasRequired(s => s.StockOrder) 
       .WithMany() 
       .HasForeignKey(s => s.JobTypeStock).WillCascadeOnDelete(true); 

as for your error "Sequence Contains No Elements" 

這個錯誤出現,當您指定LINQ查詢,使用或者.First().Single(),或.ToList()和查詢返回數據。

所以要避免使用它,.FirstOrDefault()SingleOrDefault()

顯然具有適當的空檢查。

+0

不會使用Table Per Type TPT意味着我只能使用一個導航屬性? – 2013-03-23 21:21:11

+0

一個導航屬性可以指向一個實體。這就是我試圖回答的問題。 – 2013-03-23 21:24:07

+0

其實我認爲你可以擁有一個可以指向不同類型的導航屬性。多態查詢呢?如此鏈接中關於TPH [此處]所述(http://weblogs.asp.net/manavi/archive/2010/12/24/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part -1表每層次-tph.aspx) – 2013-03-23 21:36:43