2013-03-23 68 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