1

次のシナリオを検討してください。

public class House
{
    public string Name { get; set; }
    public virtual Person Person1 { get; set; }
    public virtual Person Person2 { get; set; }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public House House { get; set; }
}

// Relationships
this.HasOptional(t => t.Person1)
    .WithRequired(t => t.House);
this.HasOptional(t => t.Person2)
    .WithRequired(t => t.House);

House のインスタンスを挿入しようとすると、MetaDataException がスローされます。

指定されたスキーマは無効です。エラー: (36,6): エラー 0040: タイプ House_Person1 が名前空間 Company.Models で定義されていません (エイリアス = Self)。

もう少しハッキングした後、これが機能すると考えました:

// Relationships
this.HasOptional(t => t.Person1)
    .WithRequired();
this.HasOptional(t => t.Person2)
    .WithRequired();

しかし、EF によって作成された Person.House プロパティはありません。この動作をエミュレートできますか (以下を参照)。

    public virtual Person Person1
    {
        get
        {
            return _person1;
        }
        set
        {
            _person1 = value;
            _person1.Haushalt = this;
        }
    }

    public virtual Person Person2
    {
        get
        {
            return _person2;
        }
        set
        {
            _person2 = value;
            _person2.Haushalt = this;
        }
    }
4

1 に答える 1

2

Person.House2 つの異なる関係 (House_Person1および) で同じナビゲーション プロパティ ( ) を使用することはできませんHouse_Person2

追加の制限は、EF が真の 1 対 1 の関係として共有主キーの関連付けのみをサポートすることです。これは、関連するHousePersonが同じ主キー値を持つ必要があることを意味します。しかし、それはそれに続き、House.Person1House.Person2同じ PK 値を持つ必要がありますHouse。言い換えればPerson1、そしてPerson2決して別人になることはできません。

リレーションシップを 1 対多のリレーションシップとしてマッピングし、アプリケーションのビジネス ロジックで aHouseが 2 つを超えないようにすることをお勧めしますPerson。(現在のマッピングではそれが許可されているため、Person1およびPerson2はオプションであるため、0 人または 1 人のみが許可されます):

public class House
{
    public string Name { get; set; }
    public virtual ICollection<Person> People { get; set; }
}

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public House House { get; set; }
}

this.HasMany(t => t.People)
    .WithRequired(t => t.House);

編集

Person2 つのナビゲーション プロパティを保持したい場合は、(ここに示すように)Houseナビゲーション プロパティを持たずに、(ビジネスの観点からこの関係が間違っている場合でも) 2 つの 1 対多の関係としてのみマッピングできます。Person

this.HasOptional(t => t.Person1)
    .WithMany();
this.HasOptional(t => t.Person2)
    .WithMany();

House最後のコード スニペットで行ったようにプロパティを使用できますがPerson、モデルから除外する必要があります。

modelBuilder.Entity<Person>()
    .Ignore(t => t.House);

Person.HousePersonはもはやナビゲーション プロパティではありません。データベースからエンティティをロードするときに (熱心なロードまたは遅延ロードで) ロードすることはできません。

于 2012-10-18T18:03:55.360 に答える