简体   繁体   English

EF Core 5 中的种子拥有类型

[英]Seed owned type in EF Core 5

I have the following configuration for which I want to provide some seed values.我有以下配置,我想为其提供一些种子值。

 void IEntityTypeConfiguration<Beneficiary>.Configure(EntityTypeBuilder<Beneficiary> builder)
    {
        builder.HasKey(pk => pk.Id);

        builder.Property(pk => pk.Id)
            .UseIdentityColumn()
            .ValueGeneratedOnAdd();

        builder.HasData(
            new
            {
                Id = -1,
            });

        builder
            .OwnsOne(self => self.Invoice,
                nav =>
                {
                    nav.ToTable("Invoices");
                    nav.Property(nav => nav.Number).HasMaxLength(16).IsRequired();
                    nav.Property(nav => nav.IssueDate).HasDefaultValueSql("getutcdate()");
                })
            .HasData(new
            {
                BeneficiaryId = -1,
                Number = "000"
            });

        builder
            .Navigation(self => self.Invoice)
            .IsRequired();
    }

I've followed this example example-to-seed but I'm getting我已经按照这个例子做种子,但我得到了

The seed entity for entity type 'Beneficiary' cannot be added because > the value '-1' provided for the property 'Id' is not of type 'long'.无法添加实体类型“受益人”的种子实体,因为 > 为属性“Id”提供的值“-1”不是“long”类型。

This is very similar to How to fix EF Core migration error on join table configuration , but for owned entity type.这与How to fix EF Core migration error on join table configuration非常相似,但适用于自有实体类型。

Be careful with fluent API overloads, as they return different things.小心流利的 API 重载,因为它们返回不同的东西。 For instance, OwnsOne without builder action delegate returns a builder for the owned entity type.例如,没有构建器操作委托的OwnsOne返回一个拥有实体类型的构建器。 But the overload with action returns the original (owner) entity builder so you can continue configuring it (the configuration of the owned entity is considered to be inside the action delegate).但是带有操作的重载会返回原始(所有者)实体构建器,因此您可以继续配置它(拥有实体的配置被认为在操作委托内)。

In your case, here在你的情况下,在这里


.OwnsOne(self => self.Invoice,
    nav =>
    {
        nav.ToTable("Invoices");
        nav.Property(nav => nav.Number).HasMaxLength(16).IsRequired();
        nav.Property(nav => nav.IssueDate).HasDefaultValueSql("getutcdate()");
    }) // <-- problem
.HasData(new
{
    BeneficiaryId = -1,
    Number = "000"
});

you are exiting the owned entity builder scope (similar to the linked post join entity builder) and the next HasData is actually defining seed data for the Beneficiary rather than for intended Invoice .您正在退出拥有的实体构建器 scope (类似于链接的连接后实体构建器),下一个HasData实际上是为Beneficiary而不是为预期的Invoice定义种子数据。 And since you are using anonymous type, C# is happily accepting it and you get that error at runtime.由于您使用的是匿名类型,因此 C# 很乐意接受它,并且您在运行时会收到该错误。

To fix the issue, simply move the data seeding at the proper place, eg要解决此问题,只需将数据播种移动到适当的位置,例如

.OwnsOne(self => self.Invoice,
    nav =>
    {
        nav.ToTable("Invoices");
        nav.Property(nav => nav.Number).HasMaxLength(16).IsRequired();
        nav.Property(nav => nav.IssueDate).HasDefaultValueSql("getutcdate()");
        // move here
        nav.HasData(new
        {
            BeneficiaryId = -1,
            Number = "000"
        });
    });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM