web-dev-qa-db-ja.com

関連付けの主要な終了を判別できません-Entity Framework Model First

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);
    }
14
Michal

プリンシパルは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はユーザーが最初に存在する必要がある(プリンシパル)ことを認識し、アドレスが続きます。

MSDNでさらに読む

また、これを参照してくださいSO答え。


コメントから更新


デザイナーで、関連付け([ユーザーとアドレス]の間の線)を選択します。プロパティウィンドウで、参照制約の[...]が付いたボタンをクリックします(または行をダブルクリックします)。プリンシパルをユーザーとして設定します。


30
Eric W.

エラー:「タイプ '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:モデルブラウザーのエンティティタイプリストからテーブルを削除し、[はい]をクリックしてから、[データベースからモデルを更新]を再度クリックします。

0
Eric Wood