17

Entity Framework 6.1.3 に次のデータ モデルがあります。

using System.Data.Entity;

public class Student
{
    public int Id { get; set; }
    public virtual Contact Contact { get; set; }
}

public class Contact
{
    public int Id { get; set; }
    public virtual Student Student { get; set; }
}

public class MyContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder builder)
    {
        builder.Entity<Contact>()
            .HasOptional(x => x.Student)
            .WithOptionalDependent(x => x.Contact)
            .WillCascadeOnDelete(true);
    }
}

public static class Program
{
    private static void Main()
    {
        Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());

        using (var context = new MyContext())
            context.Database.Initialize(force: true);
    }
}

このコードを起動すると、目的のテーブル構造が正確に得られます。

dbo.Contacts
    Id (PK)
    Student_Id (FK, NULL, CASCADE ON DELETE)

dbo.Students
    Id (PK)

ただし、エンティティStudent_Idで使用できるようにプロパティを追加したいと思います。そのため、ナビゲーションを通じて他のテーブルに参加する必要なくContact、を読むことができます。Student_Id.Student.Id

プロパティをContactエンティティに追加すると、 と の 2 つの列が表示されるかStudent_IdStudent_Id1というエラー メッセージが表示されますEach property name in a type must be unique.

列は既にデータベースにあり、必要なのはエンティティにもあることだけです。なぜそんなに面倒なのですか? 解決策はありますか?

4

2 に答える 2

9

If you want to declare the FK property in the dependent entity in an one to one relationship, I'm afraid you must use it as a PK too. EF Code First requires that PK of the dependent entity must be FK of the relationship too:

public class Contact
{
    [Key,ForeignKey("Student")]
    public int StudentId { get; set; }
    public virtual Student Student { get; set; }
}

But I think this is not what you are looking for. So, I think you have three options here:

  • You preserve your current relationship configuration.
  • Create an authentic one to one relationship.
  • Create an one to many relationship

By my experience the last one is the most adjusted to what are you trying to achieve (but that is my opinion). In this case you can work with the Fk property as you want, the only is you need to change the Contact navigation property on Student by a collection (or omit this nav. property and create an unidirectional relationship):

public class Student
{
    public int Id { get; set; }
    public virtual ICollection<Contact> Contacts { get; set; }
}

The configuration would be this way:

 builder.Entity<Contact>()
        .HasOptional(x => x.Student)
        .WithMany(x => x.Contacts)
        .HasForeignKey(x => x.StudentId)
        .WillCascadeOnDelete(true);

Update

A fourth option could be create two unidirectional relationships:

 builder.Entity<Contact>()
        .HasOptional(x => x.Student)
        .WithMany()
        .HasForeignKey(x => x.StudentId)
        .WillCascadeOnDelete(true);

 builder.Entity<Student>()
        .HasOptional(x => x.Contact)
        .WithMany()
        .HasForeignKey(x => x.ContactId)
        .WillCascadeOnDelete(true);

But this option breaks the real relation between the two tables.

于 2015-08-31T15:13:41.460 に答える