2

首先是 EF 代码的有趣继承。你认为有一个映射策略可以使这项工作吗?

所以我有一个名为“Animal”的基本抽象类和 3 个从 Animal 类派生的类,Fish、Dog 和 UnknownAnimal。Animal 类有自己的 SQL 表,Fish 和 Dog 分别有 SQL 表 Fish 和 Dog。UnknownAnimal 没有任何额外的字段,因此此类不需要 SQL 表。为了使它更容易一点,Animal SQL Table 有一个鉴别列 (TypeName) 来确定 Animal 类型。

SQL表的代码和图片如下。它既不是 TPH 也不是 TPT,而是一种混合物。我看到的唯一解决方案是使它成为 TPT,通过创建一个 SQL 表“UnknownAnimal”并指向 UnknownAnimal 类来使用该表。但我不想采用这种方式,因为 UnknownAnimal 没有任何额外的属性并且在 SQL 服务器中占用空间(不多)。

带有集成 Nunit 测试甚至数据库 .bak 文件的完整测试项目的代码。 https://bitbucket.org/RomeoQNgo/efinheritancetest/downloads

我尝试了 TPT,但这需要一个额外的 UnknownAnimal SQL 表。这意味着如果我有另一个类,如 UnknownAnimal(继承自 Animal,但没有额外的属性),那么我必须为它创建一个新表。一种简单的方法是在 Animal SQL 表中设置一个名为 TypeName 之类的鉴别器字段,并让它确定类类型。但是我不想使用 TPH,因为如果有更多的动物类型具有该动物独有的新属性(例如具有 TrunkLength 等属性的大象),那么我们必须在 Animals SQL 表中创建一个新列,我不除非没有可能,否则想走这条路。

所以我想结合使用鉴别器字段(TypeName)的TPH和TPT来确定该类唯一的动物额外属性的类类型和额外表。我想使用 Code First 并且不想为此使用任何 EDMX 文件。

我想知道目前使用 EF Code First 是否有任何好的方法。提前感谢您的帮助。

public interface IEntity2
{
    string Creator { get; set; }
}

public interface IEntity
{
    int Id { get; set; }
    string DisplayName { get; set; }
}

[Table("Animals")]
public abstract class Animal : IEntity, IEntity2
{
    public virtual int Id { get; set; }
    public virtual string DisplayName { get; set; }
    public virtual int TotalLegs { get; set; }
    public string Creator { get; set; }
}

[Table("UnknownAnimals")]
public class UnknownAnimal : Animal
{
    int test { get { return 1; } }
}

[Table("Fishes")]
public class Fish : Animal
{
    public virtual int WaterType { get; set; }
}

[Table("Dogs")]
public class Dog : Animal
{
    public virtual int FurLength { get; set; }
}

数据库图如下:

http://i.stack.imgur.com/4JiCJ.png

4

1 回答 1

2

不知何故,拥有一个类似乎是不对的UnknownAnimal(尽管我意识到它只是你现实生活中代码的抽象)。从语义上讲,未知动物是一种,Animal但它还没有类型(还没有?)。Animal通过使Animal类不是抽象的,将其存储为 可能是对现实的更好反映。这样做,您不需要UnknownAnimal表格,并且仍然不需要鉴别器列。

但是您永远无法UnknownAnimal轻松地仅从数据库中获取 s,因为context.Animals.OfType<Animal>()返回所有动物。[就个人而言,我更喜欢仅继承树的叶子是具体类型,但这可能是一些先天的心理缺陷。]

对我来说,问题是:UnknownAnimal类型本身是正确的吗?如果是这样,请使用该类型并将相对无用的表视为理所当然(以后可能会开发自己的字段)。如果不是,继承可能不是这里的正确模型,您应该使用组合(有些人认为这总是比继承更好)。

于 2012-09-14T17:35:08.190 回答