首页 > 解决方案 > EF Core 需要显式设置 id-property,尽管它是在“表拆分”场景中生成的数据库

问题描述

在 .NET Core 3.1 中使用 EF Core 我正在尝试使用表拆分,其中两个对象的内容存储在同一个 SQL 数据库表中:

public class Store {
    [Column(Order = 0), Key]
    public long StoreId { get; set; }
    public bool IsActive { get; set; }
    public string StreetName { get; set; }
    public int StreetNumber { get; set; }

    public List<BusinessHours> BusinessHours { get; set; }
}

public class BusinessHours {
    public long StoreId { get; set; }
    public Store Store { get; set; }

    public DayOfWeek Day { get; set; }
    public DateTime StartTime { get; set; }
    public DateTime EndTime { get; set; }
}

OnModelCreating 定义如下:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Store>()
        .ToTable("Stores")
        .HasMany<BusinessHours>()
        .WithOne(o => o.Store).HasForeignKey(a => a.StoreId);

    modelBuilder.Entity<BusinessHours>()
        .ToTable("Stores").HasKey(k => k.StoreId);
}

不幸的是,当我尝试使用以下方法将样本数据播种到数据库时:

var teststore = new Store {
    Name = "Chipotle Southwest",
    IsActive = true,
    StreetName = "Random Street NE",
    StreetNumber = 20,
    BusinessHours = new List<BusinessHours>()
    {
        new OpenHours { Day = DayOfWeek.Monday, StartTime = "08", EndTime = "17" },
        new OpenHours { Day = DayOfWeek.Tuesday, StartTime = "08", EndTime = "17" },
        new OpenHours { Day = DayOfWeek.Wednesday, StartTime = "08", EndTime = "17" },
        new OpenHours { Day = DayOfWeek.Thursday, StartTime = "08", EndTime = "17" },
        new OpenHours { Day = DayOfWeek.Friday, StartTime = "08", EndTime = "17" },
        new OpenHours { Day = DayOfWeek.Saturday, StartTime = "10", EndTime = "15" },
        new OpenHours { Day = DayOfWeek.Sunday, StartTime = "11", EndTime = "13" }
    }
};

_context.Stores.Add(teststore);
_context.SaveChanges();

我收到以下错误: System.InvalidOperationException:实体类型“BusinessHours”上的属性“StoreId”在尝试将实体的状态更改为“未更改”时具有临时值。显式设置永久值或确保将数据库配置为为此属性生成值。

我理解它的原因,但不幸的是,这是(并且应该)是数据库生成的值。解决此问题的正确方法是什么?

标签: c#entity-framework.net-coreentity-framework-core

解决方案


来自EF Core 文档

根据所使用的数据库提供程序,值可能由 EF 或在数据库中生成客户端。如果该值是由数据库生成的,那么 EF 可能会在您将实体添加到上下文时分配一个临时值。然后,此临时值将被 SaveChanges 期间数据库生成的值替换。

您也可以尝试使用这个 Fluent Api 配置:

modelBuilder.Entity<BusinessHours>()
            .Property(f => f.Id)
            .ValueGeneratedOnAdd();

推荐阅读