簡體   English   中英

EF6一對一可選關系單向導航屬性

[英]EF6 One-to-One Optional Relationship one-directional navigation properties

我正在研究的項目中有以下Domain模型,它們是

public class Person
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string Surname { get; set; }
    public virtual User { get; set; }
}

public class User
{
    public int Id { get; set; }
    public string LoginName { get; set; }
    public string Password { get; set; }
}

我基本上有一個Person實體和一個User實體,一個Person可以在沒有User情況下存在,但是User不能在沒有Person情況下存在。 我也只希望單向加載EF中的關系(即,當我加載Person實體時,我希望將導航屬性設置為User而不是其他方式)

我發現我必須在兩個對象上創建關系屬性以實現關系映射,並且當然不希望這樣做,也不必在一個方向檢查NULL的開銷,我寧願User實體沒有其Person屬性。

任何人都可以幫助定義正確的模型和關系映射以在運行時生成正確的EF Code-First配置和對象模型,我已經嘗試了以下方法:

modelBuilder.Entity<Person>()
    .HasOptional(t => t.User)
    .WithRequired(t => t.Person)
    .Map(x => x.MapKey("PersonId"))
    .WillCascadeOnDelete();

實現此目標的Al正在使用User屬性為NULL加載Person實體

如果有人可以幫助,將不勝感激

您需要正確配置實體:

  1. 您可以不指定類型就指定必需的關系,例如.WithRequired()
  2. 使用one-to-one關系時,兩個實體的key屬性名稱必須相同。

因此,您可以通過使用HasOptional(t => t.User).WithRequired();簡單地實現HasOptional(t => t.User).WithRequired();

為了完整起見,我在下面添加了(或多或少)完整的代碼:

  1. 實體:

     public class Person { public int Id { get; set; } public string FirstName { get; set; } public string Surname { get; set; } public virtual User User { get; set; } } public class User { public int Id { get; set; } public string LoginName { get; set; } public string Password { get; set; } } 
  2. 實體配置:

     public class PersonConfig:EntityTypeConfiguration<Person> { public PersonConfig() { HasOptional(t => t.User).WithRequired().WillCascadeOnDelete(); } } 
  3. 數據庫上下文

     public class MyDbContext:DbContext { public DbSet<Person> People { get; set; } public DbSet<User> Users { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Configurations.Add(new PersonConfig()); } } 
  4. 生成的初始遷移(使用add-migration ):

     public override void Up() { CreateTable( "dbo.People", c => new { Id = c.Int(nullable: false, identity: true), FirstName = c.String(), Surname = c.String(), }) .PrimaryKey(t => t.Id); CreateTable( "dbo.Users", c => new { Id = c.Int(nullable: false), LoginName = c.String(), Password = c.String(), }) .PrimaryKey(t => t.Id) .ForeignKey("dbo.People", t => t.Id, cascadeDelete: true) .Index(t => t.Id); } 
  5. 種子配置:

     protected override void Seed(EF.MyDbContext context) { var person1 = new Person {Id= 1, FirstName = "Andrew", Surname = "Peters" }; var person2 = new Person {Id= 2, FirstName = "Brice", Surname = "Lambson" }; var person3 = new Person {Id= 3, FirstName = "Rowan", Surname = "Miller" }; context.People.AddOrUpdate(p => p.Id, person1, person2, person3); var user1 = new User { Id = 1, LoginName = "Andrew", Password = "Peters" }; var user3 = new User { Id = 3, LoginName = "Rowan", Password = "Miller" }; context.Users.AddOrUpdate(p => p.Id, user1, user3); } 
  6. 用法:

     MyDbContext ctx = new MyDbContext(); ctx.People.ToList().ForEach(person => { System.Console.WriteLine($"Id:{person.Id}, Name: {person.FirstName} {person.Surname}"); if (person.User != null) { System.Console.WriteLine($"Found user, Id:{person.User.Id}, " + $"Login: {person.User.LoginName}, Password: {person.User.Password}"); } }); /* Output: Id:1, Name: Andrew Peters Found user, Id:1, Login: Andrew, Password: Peters Id:2, Name: Brice Lambson Id:3, Name: Rowan Miller Found user, Id:3, Login: Rowan, Password: Miller */ 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM