1

次のような基本的な継承階層があります。

public class Parent
{
    public int ParentID {get; set;}

    public string SomeOtherProperty {get; set;}
};

public class Child : Parent
{
    public string SomeChildProperty {get; set;}
};

複数の子クラスがあり、次のように、一般的な方法でデータベースに書き込むことができる Parent クラスに基づくインターフェイスを持つ Auditor オブジェクトがあります。

public class Auditor
{
    public void WriteObject(Parent p)
    {
        using (MyDbContext context = new Context)
        {
            context.Parents.Add(p);
            context.SaveChanges();
        }
    }
}

だから私はAuditorを次のように使うことができます

auditor.WriteObject(new Child1());
auditor.WriteObject(new Child2());

などなど、そして子オブジェクトを書き込むたびに、EF は DB に親行を作成しました。

私が抱えている問題は、場合によっては (おそらく 10% の時間)、子レコードを DB に書き込み、それを既存の親行にリンクしたい、つまり、外部キーを提供したいということです。

私は何かを試しました

Child1 child = new Child();
child1.ParentID = existingID;
auditor.WriteObject(child);

しかし、EF は私が提供した外部キ​​ーを無視し、新しい親レコードを作成しました。

私が書き込もうとしている Child オブジェクトに親 ID が既に存在するため、親行を挿入する必要がないことを EF に理解させる方法はありますか?

4

1 に答える 1

3

あなたの説明に基づいて少し混乱していますが、あなたが意味すると思われるシナリオに答えようとします:

オプション 1 : これが目的だと思います: 親クラスのオブジェクトを作成しています。後で、より多くの情報を取得し、それらを適切なサブクラスに「ダウンキャスト」したいとします。これは、EF ではこの方法では不可能です。オブジェクトが特定のタイプとして作成されると、それはそのままにしておく必要があります。あなたの場合のオプションは次のとおりです。

  1. このオブジェクトは (parentType) として既に存在しますか?
  2. オブジェクトの削除 (ParentType)
  3. 保存オブジェクト (ChildType)

私がここで提供できるよりも優れた言葉による説明を参照してください。

エンティティ フレームワークの既存の親レコードに子を追加する

Entity Framework によるダウンキャスト

これが意図されていることである場合は、これらの状況を回避するために、実装されているモデルの一部を再検討することをお勧めします。

オプション 2 : 親オブジェクト (この場合はスーパータイプ) にグループとして属する子要素のリストがあります。

このような場合、親をロードし、子を親に追加してから (親レベルで) 保存できます。

Child1 child = new Child();
Parent p = _context.Parents.Find(search based on ID)
p.Children.Add(child);
auditor.WriteObject(p);

更新: オプション 3

共有親IDのコメントに基づいて:あなたが今話していることはTPTの実装ではなく、ここでルールに違反しています. TPT では、各オブジェクトのすべてのテーブルの主キーである「親」テーブルに存在する単一の ID があります。2 つの子オブジェクト (任意のタイプ) が同じ主キーを持つことは決してあってはなりません。すべての場合において、子の主キーはID です。抽象度の低い用語を使用すると、混乱が解消される可能性があります。親テーブルが Animal で、子テーブルが Cat と Dog の場合、Cat と Dog が主キーを共有しないことが明らかになります (これらは異なる型であるためです。達成しようとすることはおそらく逆です。子には親のインスタンスが含まれている必要があります(質問の用語を使用)。

もう 1 つの言い方をすれば、parentID が主キーである場合、それはオブジェクトの階層の 1 つのブランチにのみ存在し、このオブジェクトを構成する継承のチェーンをまとめるためだけに機能します。たとえば、次のような階層がある場合

動物 -> 犬 -> プードル

ID=1 の新しいプードルを作成すると、ID=1 のレコード セットは 1 つだけになり、Animal、Dog、Poodle のそれぞれに 1 つの行になります。(これら 3 つのレコードはすべて同じ Poodle オブジェクト用です)、

于 2013-01-23T20:46:34.683 に答える