1

私は他のほとんどすべてが継承する基本クラスを持っています..

public abstract class MyBaseClass
{
   public int Id { get; set; }

   public int OwnerId{ get; set; }
   public virtual Org Owner{ get; set; }

}

public abstract class Party: MyBaseClass
{

}

public class Org: Party
{
   public string Name { get; set; }
   public DateTime CreationDate { get; set; }
}

私のデータ コンテキストには、次のような行があります。

public DbSet<Org> Orgs { get; set; }

このようなクエリを実行すると...

var orgs = db.Orgs;

次のエラーが表示されます。

関係 'Org_Owner' のロール 'Org_Owner_Source' では多重度が無効です。依存ロール プロパティはキー プロパティではないため、依存ロールの多重度の上限は '*' である必要があります。

この問題を解決するために、次の Fluent API コードを追加しました。

    modelBuilder.Entity<MyBaseClass>()
                .HasRequired(e => e.Owner)
                .WithMany()
                .HasForeignKey(e => e.OwnerId)
                .WillCascadeOnDelete(false);

これでエラーは解決しInvalid Multiplicityますが、その後クエリを実行すると、「シーケンスに要素が含まれていません」というエラーが返されます。データベースにヒットしている生成された SQL コードを調べると、クエリの ' from' 句が、予想どおり Orgs テーブルではなく、存在しない MyBaseClassClasses テーブルを参照していることがわかります。

移行を実行すると、「シーケンスに要素が含まれていません」というエラーもスローされます。とにかく、から継承するすべてのクラスをMyBaseClass単一の MyBaseClassClasses テーブルに非正規化することは望ましくありません。

質問:

  1. この状況で流暢な API コードは正しいですか?
  2. いいえの場合、それは何ですか?
  3. はいの場合、「シーケンスに要素が含まれていません」というエラーを解決するにはどうすればよいですか?

** * **フォローアップ編集* ** * ** * ** * ** * ** * **

私が試したもう 1 つの方法は、Fluid Mapping を削除し、次のクラス定義を使用することです。

public abstract class MyBaseClass
{
   public int Id { get; set; }

   [ForeignKey("Owner")]
   public int OwnerId{ get; set; }
   public virtual Org Owner{ get; set; }

}

public abstract class Party: MyBaseClass
{

}

public class Org: Party
{
   public string Name { get; set; }
   public DateTime CreationDate { get; set; }
}

このソリューションは、「関係 'Org_Owner' のロール 'Org_Owner_Source' では多重度が無効です。従属ロール プロパティはキー プロパティではないため、従属ロールの多重度の上限は '*' である必要があります。」をスローします。エラー。

属性が子クラスに直接入力され、流動的な API エントリが作成された場合、MyBaseClass から継承する Org 以外の他のクラスは、Owner 属性を遅延読み込みする可能性があることを発見したため、問題を部分的に回避することができました。

例えば:

public class MyOtherClass: MyBaseClass
{
   public string Name { get; set; }
   public string Whaterver { get; set; }
   public virtual Org Owner{ get; set; }
}

fluid API エントリを使用する場合:

modelBuilder.Entity<MyOtherClass>().HasRequired(x => x.Owner).WithMany().HasForeignKey(x=>x.OwnerId).WillCascadeOnDelete(true);
4

1 に答える 1