Это зависит немного на какой тип структуры таблицы вы хотите достичь. Существуют различные способы сделать это, и есть хорошее пошаговое руководство для всех вариантов, от Shared Primary Key Assocations до One-to-One Foreign Key Associations в этих ссылках. К сожалению, эти ссылки больше используют Fluent, чем Annotations. В приведенных ниже примерах используются аннотации, как вам нужно.
Shared Первичный ключ
В теории Shared Первичный ключ (горизонтальная таблица разделов, в терминах базы данных) является «правильный путь». Это также самое малое изменение, которое вы должны сделать, чтобы иметь возможность генерировать миграцию (которая будет использовать Ассоциацию общих первичных ключей). Обратите внимание, что я хотел бы изменить Person.Id
к Person.UserId
лучше показать свое намерение:
// tested in EF 5 and MVC 4.5.
[Table("UserProfile")]
public class UserProfile {
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
[Table("Person")] // not required, added for clarity in sample code
public class Person {
// Note the change of property name to reflect that this is a shared primary key,
// using the UserId column in UserProfile as the Primary Key
[Key]
public int UserId { get; set; }
[ForeignKey("UserId")]
public virtual UserProfile UserProfile { get; set; }
}
// The generated migration:
public partial class AddTable_Person : DbMigration
{
public override void Up() {
CreateTable(
"dbo.Person",
c => new {
UserId = c.Int(nullable: false),
})
.PrimaryKey(t => t.UserId)
.ForeignKey("dbo.UserProfile", t => t.UserId)
.Index(t => t.UserId);
}
public override void Down(){
DropIndex("dbo.Person", new[] { "UserId" });
DropForeignKey("dbo.Person", "UserId", "dbo.UserProfile");
DropTable("dbo.Person");
}
}
это то дает вам, в действительности есть 1:0-1
отношения между UserProfile
(который является обязательным) и People
(который является необязательным, но может иметь один пер человек в наиболее
Если вы хотите использовать Id
в Person
затем выполните следующие действия (миграция будет меняться соответственно).
public class Person {
public int Id { get; set; }
[ForeignKey("Id")]
public UserProfile UserProfile { get; set; }
}
Shared Первичный ключ с двухсторонней навигации
Если вы хотите перейти от UserProfile
к Person
у вас есть больше работы.Простое добавление public virtual Person Person { get; set; }
к UserProfile даст вам ошибку:
Unable to determine the principal end of an association between the types 'Test.Models.UserProfile' and 'Test.Models.Person'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
Итак, зафиксируем его [Required]
на Person.UserProfile
собственности (Person
требует UserProfile
). Это дает такую же миграцию, как и раньше.
// tested in EF 5 and MVC 4.5.
[Table("UserProfile")]
public class UserProfile {
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
[ForeignKey("UserId")]
public virtual Person Person { get; set; }
}
[Table("Person")] // not required, added for clarity in sample code
public class Person {
[Key]
public int UserId { get; set; }
[ForeignKey("UserId")]
[Required]
public virtual UserProfile UserProfile { get; set; }
}
Опять же, это работает, если вы используете Id
для Person
вместо UserId
:
public class Person {
[Key]
public int Id { get; set; }
[ForeignKey("Id")]
[Required]
public virtual UserProfile UserProfile { get; set; }
}
Спасибо .Down голос помогает. –
Можем ли мы проверить, какую версию MVC и EF вы используете - это может иметь значение в ваших ответах. –
MVC 4, Entity Framework 5 –