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; }
 }

当我运行迁移时,我得到描述的错误 [here][1] 所以使用抽象实体似乎不起作用。

我的问题是,如何创建可以导航到多个实体类型的导航属性?

如果 JobType = SalesOrder 然后我想导航到销售订单,如果 JobType = StockOrder 然后我想导航到库存订单。

我想使用每个层次结构的表策略 [在此处查看 TPH][2]

4

2 回答 2

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可以是 aSalesOrder或 a的属性StockOrder

您可以通过以下方式查询特定的订单类型

contex.Orders.OfType<StockOrder>()

你会注意到 EF 不知道LoggedEntity,因为

context.Set<LoggedEntity>()

会抛出异常

实体类型 LoggedEntity 不是当前上下文模型的一部分。

于 2013-03-23T23:08:10.043 回答
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; }
}

然后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);

as for your error "Sequence Contains No Elements"

当您指定的 Linq 查询使用.First()or .Single(), or.ToList()并且查询没有返回数据时,就会出现此错误。

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

显然有适当的空值检查。

于 2013-03-23T20:55:04.710 回答