11

EF Code First を使用して、2 つのエンティティ間に双方向の One-One 関係を作成したいと考えています。次のコードに問題があります。私は何をすべきだと思いますか?

public class User
{
    public string ID { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public string FirstName { get; set; }

    public int ProfileID { get; set; }
    public Profile Profile { get; set; }

}
public class Profile
{
    public int UserID { get; set; }
    public User User { get; set; }
    public int ProfileID { get; set; }
    public string ProfileName { get; set; }

    public DateTime CreateDate { get; set; }
    public DateTime LastUpdateDate { get; set; }

}

両方のエンティティにナビゲーション プロパティと外部キーの両方が必要です。

これは私にエラーを与えます。これを機能させるには、Fluent Mapping API で何ができますか?

4

1 に答える 1

18

これを使って:

public class User
{
    public string ID { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public string FirstName { get; set; }
    public Profile Profile { get; set; }
}

public class Profile
{
    [Key, ForeignKey("User")]
    public int ProfileID { get; set; }
    public string ProfileName { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime LastUpdateDate { get; set; }
    public User User { get; set; }
}

これは、EF で 1 対 1 の関係を構築する唯一の有効な方法です。従属エンティティの PK は、プリンシパル エンティティに対しても FK でなければなりません。EFでは機能しないため、EFには双方向の1対1の関係のようなものはありません。

人々が時々これを克服する方法は、プリンシパルが依存エンティティのナビゲーション コレクション + データベース内の手動で定義された一意のキーを持たない 2 つの 1 対多の関係です。手動マッピングが必要な場合:

public class User
{
    public string ID { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public string FirstName { get; set; }
    // one side MUST be nullable otherwise you have bidirectional constraint where each
    // entity demands other side to be inserted first = not possible
    public int? ProfileId { get; set; } 
    public Profile Profile { get; set; }
}

public class Profile
{
    public int ProfileID { get; set; }
    public string ProfileName { get; set; }
    public DateTime CreateDate { get; set; }
    public DateTime LastUpdateDate { get; set; }
    public int UserId { get; set; }
    public User User { get; set; }
}

マッピングでは、次を定義します。

modelBuilder.Entity<User>
            .HasOptional(u => u.Profile)
            .WithMany()
            .HasForeignKey(u => u.ProfileId);
modelBuilder.Entity<Profile>
            .HasRequired(u => u.User)
            .WithMany()
            .HasForeignKey(u => u.UserId);

次に、データベースで一意のキーを定義する必要があります。コードを使用している場合は、最初にカスタム データベース初期化r を使用します。NULL が一意の値に含まれる一意の FK が両側で要求されるため、双方向の 1 対 1 はまだ間違った概念であることに注意しUserProfileください。それはおそらくシリアライズ可能なトランザクションにつながります。UserProfile

于 2011-06-08T08:56:54.793 に答える