我的域类(简化版)中有以下内容
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; }
}
当我运行迁移时,我得到描述的错误[here] [1]因此使用抽象实体似乎不起作用。
我的问题是,如何创建可以导航到多个实体类型的导航属性?
如果JobType = SalesOrder,那么我想导航到销售订单,如果JobType = StockOrder,那么我想导航到库存订单。
我想使用Table Perirarchy策略[见TPH] [2]
答案 0 :(得分: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; }
}
您将看到迁移创建了两个表,Jobs和BaseOrders(要改进的名称)。 Job
现在有一个属性Order
,可以是SalesOrder
或StockOrder
。
您可以按
查询特定的订单类型contex.Orders.OfType<StockOrder>()
你会注意到EF不知道LoggedEntity
,因为
context.Set<LoggedEntity>()
将抛出异常
实体类型LoggedEntity不是当前上下文的模型的一部分。
答案 1 :(得分: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()
。
显然有适当的空检查。