3

以下の1対1の関係の例では、例外がスローされます

public class User
{
    public int Id { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public int Id { get; set; }
    public User User { get; set; }
}

例外は言う:

タイプ「ConsoleApplication1.Address」と「ConsoleApplication1.User」の間の関連付けの主な終わりを判別できません。この関連付けの主な目的は、リレーションシップフルーエントAPIまたはデータアノテーションのいずれかを使用して明示的に構成する必要があります。

AddressからUserプロパティを削除しても機能しますが、必要ありません。

どうすれば例外なくそのような関係を築くことができますか?

4

2 に答える 2

13

Erangaによって提供された答えは正しく、ユーザーとアドレスの間に共有主キーの関連付けを作成しますが、このマッピングタイプには制限があるため、使用したくない場合があります。

1対1の外部キーアソシエーションと呼ばれる1:1アソシエーションを作成する別の方法は次のとおりです。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Address>()
                .HasRequired(a => a.User)
                .WithOptional(u => u.Address)
                .Map(m => m.MapKey("UserId"));
}

EF Code Firstは、これを1:1の関連付けとして認識します。したがって、ユーザーとアドレスの間に双方向の関連付けを行うことができます。

ここで行う必要があるのは、UserId列に一意のキー制約を定義して、データベース側での関係を真の1対1にすることです。そのための1つの方法は、カスタム初期化クラスでオーバーライドされたSeedメソッドを使用することです。

class DbInitializer : DropCreateDatabaseAlways<Context>
{
    protected override void Seed(Context context)
    {
        context.Database.ExecuteSqlCommand("ALTER TABLE Addresses ADD CONSTRAINT uc_User UNIQUE(UserId)");
    }
}


上記のコードは、次のスキーマになります。

ここに画像の説明を入力してください

于 2012-05-08T01:21:56.847 に答える
3

流暢なAPIを使用して、関係を共有主キーとしてマッピングする必要があります。

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
         modelBuilder.Entity<Address>()
             .HasRequired(a => a.User)
             .WithOptional(u => u.Address);
    }
}
于 2012-05-06T00:42:18.487 に答える