【问题标题】:How to store two same entities in a database? Entity framework, c#如何在数据库中存储两个相同的实体?实体框架,c#
【发布时间】:2013-05-10 22:49:36
【问题描述】:

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

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) 还是我应该实现继承?那是什么类型的呢?

编辑:

在我的情况下,这两个实体是相同的,它们将来不会有任何不同的属性。

我实现了 Table-per-Hierarchy 方法,但还有另一个问题
(我有另一种类型的油和过滤器):

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 字段?

如果我在 OilFilterBase 类中包含 WarehouseId 作为属性,我将在数据库表中获得 3 个warehouse_id。

p.s. 我的Context 中也有DbSet&lt;Oil&gt;DbSet&lt;Filter&gt;,但没有DbSet&lt;OilFilterBase&gt;

【问题讨论】:

  • 试试这种方式 public class Oil : dbTable 和 public class Filter : dbTable 从一个 dbType 继承两种类型

标签: c# database entity-framework inheritance


【解决方案1】:

如果不了解您的要求,很难说什么是最好的。是什么让这两个实体不同?如果它们执行不同的功能并且恰好具有相同的属性,那么将它们存储在单独的表中可能是个好主意;这在概念上是最有意义的,并且如果您决定将来要向其中一个属性添加其他属性,这将使事情变得更容易。

另一方面,如果它们在每个级别上都完全相同,那么您是否真的需要两种不同的实体类型来存储它们也是值得的。

对于两个类服务于相关目的但在某些方面有所不同的中间立场,那么是的,某种形式的继承可能是一个好方法——要么让一个实体类型派生自另一个实体类型,要么创建一个新的公共基类型,并让两个实体都派生自该类型。

如果您认为这是最好的方法,那么它看起来是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
{
}

...然后,默认情况下,Entity Framework 将创建一个带有自动生成的鉴别器列的表,并将这两种实体类型的所有实例存储在该表中。

如果您决定这些实体类型中的任何一个都应该有额外的字段,那么您可以查看其他一些继承选项,例如 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&lt;OilFilterBase&gt;(除了DbSet&lt;Oil&gt;DbSet&lt;Filter&gt;),以便获得每个层次结构的表继承工作——试试看。

祝你好运!

【讨论】:

  • 好的,我已经添加了更多信息。希望对您有所帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-06
相关资源
最近更新 更多