私は他のほとんどすべてが継承する基本クラスを持っています..
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 テーブルに非正規化することは望ましくありません。
質問:
- この状況で流暢な API コードは正しいですか?
- いいえの場合、それは何ですか?
- はいの場合、「シーケンスに要素が含まれていません」というエラーを解決するにはどうすればよいですか?
** * **フォローアップ編集* ** * ** * ** * ** * ** * **
私が試したもう 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);