【问题标题】:Equivalent for .HasOptional in Entity Framework Core 1 (EF7)等效于 Entity Framework Core 1 (EF7) 中的 .HasOptional
【发布时间】:2016-06-04 09:37:51
【问题描述】:

考虑两个类。

public class File
{
    [Key]
    public string Id { get; set; }

    public string Message_Id { get; set; }

    internal Message Message { get; set; }
}

public class Message 
{
    [Key]
    public string Id { get; set; }       
}

在 EF6 中,对于 N : 1..0 关系,有这个流畅的 API。

modelBuilder.Entity<File>()
            .HasOptional(e => e.Message ).WithMany().HasForeignKey(e => e.Message_Id);

Entity Framework Core 1 中的等价物是什么?

谢谢

【问题讨论】:

    标签: entity-framework asp.net-core entity-framework-core .net-core asp.net-core-1.0


    【解决方案1】:

    在 EF 7 中找不到等效方法。按照惯例,CLR 类型可以包含null 的属性将被配置为可选。那么决定关系是否可选的决定因素是 FK 属性是否分别为nullable

    综上所述,由于您的Message_Id FK 属性为string,它已经接受null 值,所以如果您使用以下Fluent Api 配置:

    modelBuilder.Entity<File>()
                .HasOne(s => s.Message)
                .WithMany()
                .HasForeignKey(e => e.Message_Id)
    

    EF 会将您的关系配置为可选(或 N : 0..1 根据要求)。

    如果您的 FK 属性是像 int 这样的值类型,您应该将其声明为可为空 (int?)。

    我还注意到现在你有一个带有internal 访问修饰符的导航属性。您应该始终将您的实体属性声明为public

    【讨论】:

    • 只是添加一个观察:即使类型本身可以为空,EF 也会根据需要配置关系,给定属性上的 [Required] 注释。
    • 不要以为这是真的。 EF6 和 EF Core 都能够表示 1 : 0..1 关系,因为 EntityA.PK 是 EntityB.PK 的外键
    • 对此我深表歉意。以后我会听取你的建议
    • You should always declare your entity properties as public. 这是不正确的。如果您不想在类之外公开某些内容,可以将其声明为 protected internal 以便 Entity Framework 仍然可以使用该属性,但不能被其他任何东西访问。
    • HasOne() 是否等同于 HasOptional()?
    【解决方案2】:

    在 EF Core 中,您可以使用两种方式关联两个表:

    • 内部OnModelCreating

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          base.OnModelCreating(modelBuilder);            
      
          modelBuilder.Entity<File>()
                      .HasOne(c => c.Message)
                      .WithOne()
                      .HasForeignKey(c => c.MessageId)                           
      }
      
    • 创建新类 FileConfiguration 并在 OnModelCreating 内部调用它:

      public class FileConfiguration : IEntityTypeConfiguration<File>
      {
          public void Configure(EntityTypeBuilder<File> builder)
          {           
              builder.ToTable("File");            
      
              // Id
              builder.HasKey(c => c.Id);
              builder.Property(c => c.Id)
                     .ValueGeneratedOnAdd();
      
              // Message
              builder.HasOne(c => c.Message)
                     .WithOne(c => c.File)
                     .HasForeignKey<Message>(c => c.MessageId)
                     .OnDelete(DeleteBehavior.Restrict);
          }
      }
      

      在 OnModelCreating 里面放下面的代码:

      protected override void OnModelCreating(ModelBuilder modelBuilder)
      {
          base.OnModelCreating(modelBuilder);
      
          modelBuilder.ApplyConfiguration(new FileConfiguration());                                       
      }
      

    【讨论】:

    • 我该怎么做才能自我参考。
    猜你喜欢
    • 2021-09-18
    • 2017-05-07
    • 2023-01-27
    • 1970-01-01
    • 1970-01-01
    • 2019-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多