EFのバグかもしれないと思うものの再現があります。1つのテーブルを2つのエンティティに分割したいと思います。これらの各エンティティには、3番目のエンティティへの参照が含まれています。2つの参照は、同一の外部キープロパティ名で公開する必要があります。それらは同じテーブルの列にマップされるため、構成(またはこの例では属性)を使用して列名を一意にします。
モデルをロードしようとすると、EFから上記の例外が発生します。FKプロパティの1つの名前を変更すると、エラーはなくなります。
これが私のモデルです。コードはそのまま動作します。問題を再現するには、名前Foo2.Foo3Id1
をに変更しFoo3Id
ます。これは、必要な値です。
なぜあなたはそれをしたいのですか?
2つのプロパティが同じ名前である必要がある理由がわからない場合は、ここで説明します。
いくつかの住所(たとえば、住所と請求先住所)を含むテーブルがあります。これは既存のデータベースであるため、テーブル構造を変更することはできません。各アドレスは、一連の標準列で表されます。各列の名前には、アドレスの種類を識別するプレフィックスと、アドレスの一部を識別するサフィックス(、、などBillingAddressLine1
)がBillingAddressZipCode
ありPostalAddressLine1
ます。
複合型を使用するとこれを処理できるように思われます。ただし、さらに複雑な問題があります。各アドレスには、テーブルCityId
を参照するが含まれていCities
ます。複合型は、関係とナビゲーションプロパティをサポートしていません。したがって、私の意図する解決策は、代わりにテーブル分割を使用し、アドレスプロパティの各セットを独自のエンティティに分割することです。アドレスを表す各エンティティは、たとえば基本タイプから派生するかAddress
、インターフェイスを実装しますIAddress
。
テーブル分割では、複数のタイプが同じテーブルにマップされる場合、それらすべてが相互にナビゲーションプロパティを持っている必要があるという制限に注意して注意します。
以下のコードではFoo1
、Foo2
は両方ともアドレスタイプです(そしていくつかの一般的なインターフェイスを実装します)。 Foo3
ですCity
。これは私が思いついた問題の最も単純な再現です。
コードサンプル
class Program
{
static void Main(string[] args)
{
// Use NuGet to import EF 5 into the project.
// This code is just enough to cause the metadata to be loaded and therefore demo the error.
using (Context cx = new Context())
{
var qq = from f in cx.Foo3s
where f.Foo1s.Any()
select f;
}
}
}
[Table("Foo")]
public class Foo1
{
[Key]
public virtual int Id { get; set; }
[Required]
public virtual Foo2 Foo2 { get; set; }
[ForeignKey("Foo3")]
[Column("Foo1_Foo3Id")]
public virtual int? Foo3Id { get; set; }
public virtual Foo3 Foo3 { get; set; }
}
[Table("Foo")]
public class Foo2
{
[Key]
public virtual int Id { get; set; }
[Required]
public virtual Foo1 Foo1 { get; set; }
// Re-name the following property to Foo3Id (rather than Foo3Id1) and the model won't load.
// You get "InvalidOperationException: Sequence contains more than one matching element."
[ForeignKey("Foo3")]
[Column("Foo2_Foo3Id")]
public virtual int? Foo3Id1 { get; set; }
public virtual Foo3 Foo3 { get; set; }
}
[Table("Foo3")]
public class Foo3
{
[Key]
public virtual int Id { get; set; }
[InverseProperty("Foo3")]
public virtual ICollection<Foo1> Foo1s { get; set; }
[InverseProperty("Foo3")]
public virtual ICollection<Foo2> Foo2s { get; set; }
}
public class Context : DbContext
{
public DbSet<Foo3> Foo3s { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// Don't think we can configure 1:1 relationship using just attributes.
var foo2 = modelBuilder.Entity<Foo2>();
foo2.HasRequired(q => q.Foo1)
.WithRequiredPrincipal(q => q.Foo2);
}
}
これはバグですか?私は何か間違ったことをしていますか?既知のEF制限ですか?