Visual Studioでエンティティデータモデルを作成しました。これで、Modelから生成されたSQLクエリとC#クラスのファイルができました。
質問:
クラスはアノテーションやコードビハインドなしで生成されます(Fluent API)。大丈夫ですか?アプリケーションを実行しようとしましたが、例外がスローされました。
タイプ 'Runnection.Models.Address'と 'Runnection.Models.User'の間の関連付けの主な終了を判別できません。この関連付けの主要な端は、リレーションシップFluent APIまたはデータアノテーションを使用して明示的に構成する必要があります。
「Model First」でFluent APIが使えないと読みました。じゃあどうすればいい?
コード:
ユーザー
public partial class User
{
public User()
{
this.Events = new HashSet<Event>();
this.CreatedEvents = new HashSet<Event>();
}
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Photo { get; set; }
public int EventId { get; set; }
public string Nickname { get; set; }
public OwnerType OwnerType { get; set; }
public NetworkPlaceType PlaceType { get; set; }
public virtual ICollection<Event> Events { get; set; }
public virtual Address Address { get; set; }
public virtual ICollection<Event> CreatedEvents { get; set; }
public virtual Owner Owner { get; set; }
}
住所
public partial class Address
{
public int Id { get; set; }
public string Street { get; set; }
public string StreetNumber { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
public virtual User User { get; set; }
}
コンテキスト
// Model Firstはこのメソッドを使用しません
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Address>().HasRequired(address => address.User)
.WithRequiredDependent();
modelBuilder.Entity<User>().HasRequired(user => user.Address)
.WithRequiredPrincipal();
base.OnModelCreating(modelBuilder);
}
プリンシパルは1対1の関係で指定する必要があります。
public partial class Address
{
[Key, ForeignKey("User")]
public int Id { get; set; }
public string Street { get; set; }
public string StreetNumber { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
public string Country { get; set; }
public virtual User User { get; set; }
}
FK制約を指定することにより、EFはユーザーが最初に存在する必要がある(プリンシパル)ことを認識し、アドレスが続きます。
デザイナーで、関連付け([ユーザーとアドレス]の間の線)を選択します。プロパティウィンドウで、参照制約の[...]が付いたボタンをクリックします(または行をダブルクリックします)。プリンシパルをユーザーとして設定します。
エラー:「タイプ 'Providence.Common.Data.Batch'と 'Providence.Common.Data.Batch'の間の関連付けのプリンシパルエンドを特定できません。この関連付けのプリンシパルエンドは、リレーションシップFluent APIまたはデータアノテーションのいずれか。」.
ただし、これは同じテーブルであることに注意してください。
原因:データベースはMS SQL Serverでした。残念ながら、MS SQL ServerのManagement Studioが外部キーを追加すると、それ自体にリンクしているバッチテーブルのバッチID列としてデフォルトの外部キーが追加されます。あなたは開発者として、本当に外部キーへの別のテーブルとIDを選択することを想定していますが、失敗した場合でも、自己参照FKを入力できます。
解決策:解決策は、デフォルトのFKを削除することでした。
原因2:別の状況では、現在のテーブルは修正されている可能性がありますが、EFのedmxが実行されたときのテーブルの古い履歴イメージには、デフォルトのFKがありました。
解決策2:モデルブラウザーのエンティティタイプリストからテーブルを削除し、[はい]をクリックしてから、[データベースからモデルを更新]を再度クリックします。