等效于 Entity Framework Core 1 (EF7) 中的 .HasOptional

Posted

技术标签:

【中文标题】等效于 Entity Framework Core 1 (EF7) 中的 .HasOptional【英文标题】:Equivalent for .HasOptional in Entity Framework Core 1 (EF7) 【发布时间】: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 中的等价物是什么?

谢谢

【问题讨论】:

【参考方案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());                                       

【讨论】:

我该怎么做才能自我参考。

以上是关于等效于 Entity Framework Core 1 (EF7) 中的 .HasOptional的主要内容,如果未能解决你的问题,请参考以下文章

什么是 Entity Framework Core 属性等价于 modelBuilder 的 HasDefaultValueSql?

如何使用 Entity Framework Core 获取主键值

使用 Entity Framework Core 在运行时迁移

使用Entity Framework Core需要注意的一个全表查询问题

微软发布 Entity Framework EF Core 8 或 EF8

微软发布 Entity Framework EF Core 8 或 EF8