2

最初にEFコードの興味深い継承。これを機能させることができるマッピング戦略があると思いますか?

したがって、「Animal」と呼ばれる基本抽象クラスと、Animalクラス、Fish、Dog、UnknownAnimalから派生した3つのクラスがあります。動物クラスには独自のSQLテーブルがあり、FishとDogにはそれぞれSQLテーブルFishとDogがあります。UnknownAnimalには追加のフィールドがないため、このクラスにSQLテーブルは必要ありません。少し簡単にするために、Animal SQL Tableには、Animalタイプを判別するための識別子列(TypeName)があります。

SQLテーブルのコードと図を以下に示します。TPHでもTPTでもありませんが、混合物です。私が見る唯一の解決策は、SQLテーブル「UnknownAnimal」を作成し、このテーブルを使用するようにUnknownAnimalクラスを指定することにより、TPTにすることです。ただし、UnknownAnimalには追加のプロパティがなく、SQLサーバーのスペースを占有しているため(それほど多くはありません)、この方法ではアプローチしたくありません。

統合Nunitテストとデータベース.bakファイルを含む完全なテストプロジェクトのコード。 https://bitbucket.org/RomeoQNgo/efinheritancetest/downloads

TPTを試しましたが、追加のUnknownAnimalSQLテーブルが必要でした。つまり、UnknownAnimal(Animalから継承しますが、追加のプロパティはありません)のような別のクラスがある場合は、そのための新しいテーブルを作成する必要があります。簡単なアプローチの1つは、Animal SQLテーブルにTypeNameのような識別フィールドを設定し、それによってクラスタイプを決定することです。ただし、TPHを使用したくないのは、その動物に固有の新しいプロパティを持つ動物タイプ(TrunkLengthなどのプロパティを持つ象など)が多い場合は、AnimalsSQLテーブルに新しい列を作成する必要があるためです。可能な方法がない限り、この道を進みたい。

そこで、識別フィールド(TypeName)を使用するTPHとTPTの両方を組み合わせて、クラスタイプと、そのクラスに固有の動物の追加プロパティの追加テーブルを決定したいと思います。コードファーストを使用したいのですが、これにEDMXファイルを使用したくありません。

現在EFコードファーストでこれに良いアプローチがあるのだろうか。よろしくお願いします。

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 に答える