3

次のようなモデル階層構成があります。

[Table("A")]
abstract class A { }

class B : A { } // treated as abstract

[Table("C")]
class C : B { }

これにより、A と B の TPH と C の TPT が生成されます。これまでのところ、これはうまく機能しているようです。2 つのデータベース テーブルが生成されます。A モデル レコードと B モデル レコードの両方を含む "A" と、テーブル "A" にまだ保持されていない C モデル レコード列のみを含む "C" です。

表 A の TPH 配置については、生成された "Discriminator" 列があり、タイプ A とタイプ B を区別するために EF CF が独自に作成します。ただし、名前を変更したいと思います。この投稿のために、新しい名前は "Type" かもしれません。

これを行う方法を文書化したチュートリアルは、これを示唆しているようです:

modelBuilder.Entity<A>()
   .Map<B>(m=>m.Requires("Type").HasValue(typeof(B).Name))
   .Map<C>(m=>m.Requires("Type").HasValue(typeof(C).Name));

ただし、データベースの生成中に、タイプ A、B、および C のモデルが同じテーブルに追加されているという実行時エラーが発生し、「マッピング条件を使用して行を区別できる」ため、これはうまくいかないようです。これらのタイプがマップされていること。」(これが何を意味するにせよ。)

私も試しました:

modelBuilder.Entity<A>()
    .Map<B>(m=>m.Requires("Type"))
    .Map<C>(m=>m.Requires("Type"));

.. としても ..

modelBuilder.Entity<A>().Map(m=>m.Requires("Type"));

.. これらの試みはコンパイルされ、実行時エラーは発生しませんが、Discriminator 列が「Discriminator」のままであるため、効果はないようです。

A に "Discriminator" という名前の新しい文字列プロパティを作成しようとしましたが、後でプロパティの列メタデータの名前を変更しようとしましたが、2 つの "Discriminator" 列、"Discriminator" と "Discriminator1" ができました。

アイデア?

4

2 に答える 2

1

厳密には答えではありませんが、アプローチが機能することを確認するだけです...

使用している TPH 構造の識別子フィールドの名前を変更できました。階層には、型を区別するための列挙値があります。
A は基本クラス、B はもう少し洗練されたバージョン、C、D、E は具象クラスです。

クラス A
クラス B : A
クラス C : B
クラス D : B
クラス E : A

modelBuilder.Entity<A>()
            .Map<B>(m => m.Requires("TypeId").HasValue((int)MyType.ClassB))
            .Map<C>(m => m.Requires("TypeId").HasValue((int)MyType.ClassC))
            .Map<D>(m => m.Requires("TypeId").HasValue((int)MyType.ClassD))
            .Map<E>(m => m.Requires("TypeId").HasValue((int)MyType.ClassE));

具象クラスとして使用されていない場合でも、すべての派生クラスの型を含めることを覚えておく必要がありました。元々、B は必須ではなく、識別子フィールドが表示され続けると考えていたため、B を含めるのを忘れていました。

別のテーブルにあるにもかかわらず、C クラスをマップしようとすると、EF が少し混乱することが想像できます。

コメントで言及したエラー メッセージは、HasValue 要件の一部が異なるクラス タイプに対して同じ値を生成しているように聞こえます。

編集:同じエラーメッセージに対処しているように見えるこれ
を 読んでください。

于 2011-07-11T12:26:36.973 に答える
0

C識別子はTPH階層の一部ではないため、マップすることはできません。これだけ試してみてください:

modelBuilder.Entity<A>()
            .Map<B>(m=>m.Requires("Type").HasValue(typeof(B).Name));
于 2011-07-11T08:57:57.363 に答える