【问题标题】:EF6 One-to-One Optional Relationship one-directional navigation propertiesEF6 一对一可选关系单向导航属性
【发布时间】:2016-04-10 00:22:54
【问题描述】:

我正在从事的项目中有以下领域模型,它们是

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 实体,没有User 可以存在Person,但是没有Person 就不能存在User。我也只希望单向加载 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();

这个实现的目标是使用 NULL 的 User 属性加载 Person 实体

如果有人能提供帮助,将不胜感激

【问题讨论】:

    标签: c# entity-framework ef-code-first entity-framework-6 ef-fluent-api


    【解决方案1】:

    您需要正确配置实体:

    1. 您可以在不指定类型的情况下指定所需的关系,例如.WithRequired()
    2. 使用one-to-one 关系时,key 属性的名称在两个实体中必须相同。

    因此,您可以使用HasOptional(t =&gt; 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
      */
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-18
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多