以下は、2つの同様の流暢なAPI構成です。
WithMany()
_modelBuilder.Entity<Country>()
.HasRequired(cou => cou.Currency)
.WithMany()
.WillCascadeOnDelete(false);
_
WithOptional()
_modelBuilder.Entity<Country>()
.HasRequired(cou => cou.Currency)
.WithOptional()
.WillCascadeOnDelete(false);
_
ここで表現しようとしているのは、すべてのCountry
には具体的なCurrency
が必要ですが、Currency
はゼロ、1つ、または複数の国に割り当てることができます。
上記のステートメントのどれを使用する必要がありますか?言い換えれば、.WithMany()
演算子と.WithOptional()
演算子の違いは正確には何ですか?
モデルが次のようになる場合:
public class Country
{
public int CountryId { get; set; }
public Currency Currency { get; set; }
}
public class Currency
{
public int CurrencyId { get; set; }
}
その後.。
modelBuilder.Entity<Country>()
.HasRequired(cou => cou.Currency)
.WithOptional()
.WillCascadeOnDelete(false);
...データベースに外部キー関係を作成します。ここで、CountryId
テーブルのCountries
は主キーであり、CurrencyId
テーブルのCurrencies
への外部キーです。同時に、Countries
テーブルには単一の列のみCountryId
があります。 Currencies
レコードは、関連するCountries
レコードがなくても存続できます。ただし、Currencies
レコードに関連するCountries
レコードがある場合、外部キーは同時に主キーであるCountryId
であるため、1つしか存在できません。 1つのレコードで。したがって、関係Currencies -> Countries
は1-to-0...1
。
他の例.。
modelBuilder.Entity<Country>()
.HasRequired(cou => cou.Currency)
.WithMany()
.WillCascadeOnDelete(false);
...データベースのCurrencyId
テーブルに2番目の列Countries
を作成します。これは、null許容ではなく、CurrencyId
への外部キーです。 Currencies
テーブルの。したがって、ここでは、外部キーが主キーと同一ではなく別の列になっているため、Currencies
レコードに関連するCountries
レコードがないか、1つまたは複数ある可能性があります。したがって、Countries
テーブルの複数の行が同じ外部キーを持つ可能性があります。関係 Currencies -> Countries
ここは 1-to-0...n
。
編集
異なる構成の2つのモデルに対して次のコードを使用すると...
Country country1 = new Country();
Country country2 = new Country();
Currency currency = new Currency();
country1.Currency = currency;
country2.Currency = currency;
context.Countries.Add(country1);
context.Countries.Add(country2);
context.SaveChanges();
...次に、2番目のケース(.WithMany)が機能します。データベースに2つの新しい国と1つの通貨を取得します。
ただし、少し奇妙なことに、2番目のケース(.HasOptional)では、最初の国のみが保存され、2番目の国は単に無視されます。実際、私は例外が発生することを期待していました。それをバグと見なす必要があるかどうかはわかりません。
Edit2
上記の例の順序を...に変更します。
context.Countries.Add(country1);
context.Countries.Add(country2);
country1.Currency = currency;
country2.Currency = currency;
...「。HasOptional」の場合に予期される例外をスローします。