我有两个属性完全相同的实体:

public class Oil
{
    public Guid Id { get; set; }
    public string Title { get; set; }
    public int Price { get; set; }
    public int Ammount { get; set; }
}

public class Filter
{
    public Guid Id { get; set; }
    public string Title { get; set; }
    public int Price { get; set; }
    public int Ammount { get; set; }
}

问题:
1)我能把它们放在一张桌子里吗?如果是,那怎么办?
2)还是应该实现继承?那什么类型呢?
编辑:
在我的例子中,这两个实体是相同的,它们在未来不会有任何不同的属性。
我实现了按层次结构的表方法,但还有一个问题
(我有另一种类型,收集了机油和滤清器):
public class Warehouse
{
    public Guid Id { get; set; }
    public ICollection<Filter> Filters { get; set; }
    public ICollection<Oil> Oils { get; set; }
}

所以,当我创建数据库时,我会在其中得到Warehouse_IdWarehouse_Id1字段。我不希望oil和filter类中包含Warehouse属性,如何在db表中只获取一个warehouse id字段?
如果我将warehouse id作为属性包含在oilfilterbase类中,我将在数据库表中得到3个warehouseid。
p.s.我的DbSet<Oil>中也有DbSet<Filter>Context,而没有DbSet<OilFilterBase>

最佳答案

如果不了解更多的需求,很难说什么是最好的。是什么使这两个实体不同?如果它们执行不同的函数,恰好具有相同的属性,那么将它们存储在单独的表中可能是一个好主意;这在概念上是最有意义的,而且如果您决定在将来向其中一个表添加其他属性,则会使事情变得更容易。
另一方面,如果它们在每个级别上都是相同的,那么还应该询问是否真的需要两种不同的实体类型来存储它们。
在中间阶段,两个类服务于相关的目的,但在某些方面也有所不同,那么是的,某种形式的继承可能是一种好方法——要么让一个实体类型从另一个实体类型派生,要么创建一个新的公共基类型,让两个实体都从中派生。
如果您认为这是最好的方法,那么它看起来很适合Table-per-Hierarchy映射。您可以重新构造代码,如下所示:

public abstract class OilFilterBase
{
  public Guid Id { get; set; }
  public string Title { get; set; }
  public int Price { get; set; }
  public int Amount { get; set; }
}

public class Oil : OilFilterBase
{
}

public class Filter : OilFilterBase
{
}

…然后实体框架将在默认情况下创建一个具有自动生成的鉴别器列的表,并将两种实体类型的所有实例存储在该表中。
如果您决定这些实体类型中的任何一个都应该有额外的字段,那么您可以查看其他一些继承选项,例如Table-per-Type,它们为每个实体类型创建单独但相关的表。
首先要做的是确定这些类在概念上是如何组合在一起的,然后找出用ef术语实现它们的最佳方法。如果你能提供更多关于这些实体是什么以及它们是如何工作的信息,这里的人们就更容易给出好的建议。
对编辑的响应:
我认为额外的列(Warehouse_IdWarehouse_Id1)的情况是:
因为您要分别为OilFilter设置关系,所以假设您想使用基类的WarehouseId属性作为外键是不舒服的——如果您只想为Oil而不是Filter设置关系呢?在这种情况下,它不应该写入基类列。因此,它决定创建新的属性。
幸运的是,您可以使用[ForeignKey()]属性(或fluent api)告诉它您真正想要的是什么,如下所示:
using System.ComponentModel.DataAnnotations.Schema;

public abstract class OilFilterBase
{
  public Guid Id { get; set; }
  public string Title { get; set; }
  public int Price { get; set; }
  public int Amount { get; set; }
  public Guid WarehouseId { get; set; }
}

public class Oil : OilFilterBase
{
}

public class Filter : OilFilterBase
{
}

public class Warehouse
{
  public Guid Id { get; set; }

  [ForeignKey("WarehouseId")]
  public virtual ICollection<Filter> Filters { get; set; }

  [ForeignKey("WarehouseId")]
  public virtual ICollection<Oil> Oils { get; set; }
}

另外,我认为您需要在上下文中包含一个DbSet<OilFilterBase>(除了DbSet<Oil>DbSet<Filter>)以便使表的每层次继承工作——试试看。
祝你好运!

10-07 16:10
查看更多