Entity framework 5 如何创建可以导航到多个实体类型的导航属性?
我的域类中有以下内容(简化) 我的背景如下Entity framework 5 如何创建可以导航到多个实体类型的导航属性?,entity-framework-5,Entity Framework 5,我的域类中有以下内容(简化) 我的背景如下 public class Context : DbContext { public DbSet<Job> Jobs { get; set; } public DbSet<StockOrder> StockOrders { get; set; } public DbSet<SalesOrder> SalesOrders { get; set; } } 公共类上下文:DbContext { 公共数据库集作业{g
public class Context : DbContext
{
public DbSet<Job> Jobs { get; set; }
public DbSet<StockOrder> StockOrders { get; set; }
public DbSet<SalesOrder> SalesOrders { get; set; }
}
公共类上下文:DbContext
{
公共数据库集作业{get;set;}
public DbSet StockOrders{get;set;}
公共数据库集销售订单{get;set;}
}
当我运行迁移时,我得到了[here][1]所描述的错误,因此使用抽象实体似乎不起作用
我的问题是,如何创建可以导航到多个实体类型的导航属性
如果JobType=SalesOrder,则我希望导航到sales order;如果JobType=StockOrder,则我希望导航到stock order
我想根据继承人策略使用一张表[参见此处的TPH][2]
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; }
}
然后在modelbuilder
中通过fluent-API在配置中链接它们
HasRequired(s => s.SalesOrder)
.WithMany()
.HasForeignKey(s => s.JobTypeSales).WillCascadeOnDelete(true);
HasRequired(s => s.StockOrder)
.WithMany()
.HasForeignKey(s => s.JobTypeStock).WillCascadeOnDelete(true);
及
当指定的Linq查询使用.First()
或.Single()
或.ToList()
时,会出现此错误,并且查询未返回任何数据
因此,要避免使用,.FirstOrDefault()
或SingleOrDefault()
显然,通过适当的空检查
你不能这样做。至少现在不行。导航属性是描述实体之间关系的一种方式。它们最多表示某种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; }
}
然后在modelbuilder
中通过fluent-API在配置中链接它们
HasRequired(s => s.SalesOrder)
.WithMany()
.HasForeignKey(s => s.JobTypeSales).WillCascadeOnDelete(true);
HasRequired(s => s.StockOrder)
.WithMany()
.HasForeignKey(s => s.JobTypeStock).WillCascadeOnDelete(true);
及
当指定的Linq查询使用.First()
或.Single()
或.ToList()
时,会出现此错误,并且查询未返回任何数据
因此,要避免使用,.FirstOrDefault()
或SingleOrDefault()
显然,通过适当的空检查。诀窍是让EF不知道LoggedEntity类。根据以下示例重塑实体:
公共枚举作业类型
{
SalesOrder=1,
库存订单=2
}
公共抽象类日志身份
{
公共int Id{get;set;}
公共字符串名称{get;set;}//和其他字段
}
公共抽象类BaseOrder:LoggedEntity//orders的新基类!!
{ }
公共类SalesOrder:BaseOrder
{ }
公共类股票订单:BaseOrder
{ }
公共类职位:LoggedEntity
{
public JobType JobType{get;set;}//JobType枚举
公共虚拟基序{get;set;}
}
公共类Tph2Context:DbContext
{
公共数据库集作业{get;set;}
公共数据库集命令{get;set;}
}
您将看到迁移创建了两个表,Jobs和BaseOrders(名称有待改进)Job
现在有一个属性Order
,可以是SalesOrder
或StockOrder
您可以通过以下方式查询特定订单类型:
contex.Orders.OfType()
您会注意到EF不知道日志身份,因为
context.Set()
将抛出异常
实体类型LoggeIdentity不是当前上下文的模型的一部分
诀窍是让EF忘记LoggedEntity类。根据以下示例重塑实体:
公共枚举作业类型
{
SalesOrder=1,
库存订单=2
}
公共抽象类日志身份
{
公共int Id{get;set;}
公共字符串名称{get;set;}//和其他字段
}
公共抽象类BaseOrder:LoggedEntity//orders的新基类!!
{ }
公共类SalesOrder:BaseOrder
{ }
公共类股票订单:BaseOrder
{ }
公共类职位:LoggedEntity
{
public JobType JobType{get;set;}//JobType枚举
公共虚拟基序{get;set;}
}
公共类Tph2Context:DbContext
{
公共数据库集作业{get;set;}
公共数据库集命令{get;set;}
}
您将看到迁移创建了两个表,Jobs和BaseOrders(名称有待改进)Job
现在有一个属性Order
,可以是SalesOrder
或StockOrder
您可以通过以下方式查询特定订单类型:
contex.Orders.OfType()
您会注意到EF不知道日志身份,因为
context.Set()
将抛出异常
实体类型LoggeIdentity不是当前上下文的模型的一部分
按类型使用表TPT不意味着我只能使用一个导航属性吗?一个导航属性只能指向一个实体。这就是我试图回答的。实际上我认为你可以有一个导航属性,可以指向不同的类型。多态查询呢?正如在这个关于TPH的链接中所解释的,使用每种类型的表TPT不意味着我只能使用一个导航属性吗?一个导航属性只能指向一个实体。这就是我试图回答的。实际上我认为你可以有一个导航属性,可以指向不同的类型。多态查询呢?正如在这个关于TPH的链接中所解释的,我想我使用的是一个表一继承人策略,你是说所有的类都映射到一个表吗?我可以想象你们用SalesOrder和StockOrder做这些,但Job是一个完全不同的实体。可能您的问题更深,即使用基类
LoggedEntity
。这会给您的继承带来很大麻烦。LoggedEntity实际上不是一个表。它是抽象的,因此是抽象的