【问题标题】:Seeding Data - Owned Type without Id播种数据 - 没有 ID 的自有类型
【发布时间】:2021-04-19 09:29:56
【问题描述】:

我有一个描述组织的实体,包括其邮政地址。地址存储在一个属性 (PostalAddress) 中,组织的所有属性都存储并展平在同一个数据库表中。配置编译并应用迁移没有任何问题 - 如果我不播种数据。我已经在 Razor Pages 中测试了标准 CRUD - 没问题。

OnModelCreating 中添加种子时,编译时出现错误。

无法添加实体类型“Organization.PostalAddress#PostalAddress”的种子实体,因为没有为所需的属性“OrganizationId”提供值。

这条消息让我很困惑,因为OrganizationPostalAddress 都没有OrganizationId 属性。数据库中也不存在影子属性。关于导致问题的任何想法?

public abstract class BaseEntity<TEntity>
{
    [Key] public virtual TEntity Id { get; set; }
}

public class MyOrganization : BaseEntity<long>
{
    public string Name { get; set; }                    // Name of the Organization
    public PostalAddress PostalAddress { get; set; }    // Postal address of the Organization
    public string Email { get; set; }                   // Email of the Organization
}

public class PostalAddress
{
    public string StreetAddress1 { get; set; }  // Address line 1
    public string ZipCode_City { get; set; }    // Zip code
    public string Country { get; set; }         // Country
}
public void Configure(EntityTypeBuilder<Organization> builder)
{
    builder
        .ToTable("Organizations")
        .HasKey(k => k.Id);

    // Configure PostalAddress owned entity
    builder
        .OwnsOne(p => p.PostalAddress, postaladdress =>
        {
            postaladdress
                .Property(p => p.StreetAddress1)
                .HasColumnName("StreetAddress1")
                .HasColumnType("nvarchar(max)")
                .IsRequired(false);
            postaladdress
                .Property(p => p.ZipCode_City)
                .HasColumnName("ZipCode_City")
                .HasColumnType("nvarchar(max)")
                .IsRequired(false);
            postaladdress
                .Property(p => p.Country)
                .HasColumnName("Country")
                .HasColumnType("nvarchar(max)")
                .IsRequired(false);
        });
}

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder
        .AddDBConfigurations();

    // Seed data
    builder
        .Entity<Organization>(b =>
        {
            b.HasData(new Organization 
            {
                Id = 1,
                Name = "Test Organization",
                Email = "nobody@nowhere.com"
            });
            b.OwnsOne(e => e.PostalAddress)
                .HasData(new 
                { 
                    StreetAddress1 = "1600 Pennsylvania Avenue NW", ZipCode_City = "Washington, D.C. 20500", Country = "USA"
                });
        }); 
}

【问题讨论】:

  • 它是由约定造成的,如果您需要建立一对一的关系,您需要添加 MyOrganization 的虚拟属性并在播种数据时在邮政地址对象中添加 organizationId 这也有助于您配置一对一的关系@ 987654321@
  • 只是为了澄清。这真的是一对一的关系吗?没有 PostalAddress 对象存储在表中,但都因为这个原因而被展平?在模型中添加一个 organizationId 似乎不合逻辑。
  • 您能否将您的回复上移作为答案?我愿意接受。

标签: asp.net-core entity-framework-core ef-fluent-api asp.net-core-configuration owned-types


【解决方案1】:

异常消息很神秘,但很有帮助。当您将OrganizationId 添加到PostalAddress 的种子代码中时,它会起作用。

modelBuilder
    .Entity<Organization>(b =>
    {
        b.HasData(new Organization
        {
            Id = 1, // Here int is OK.
            Name = "Test Organization",
            Email = "nobody@nowhere.com"
        });
        b.OwnsOne(e => e.PostalAddress)
            .HasData(new
            {
                OrganizationId = 1L, // OrganizationId, not Id, and the type must match.
                StreetAddress1 = "1600 Pennsylvania Avenue NW",
                ZipCode_City = "Washington, D.C. 20500",
                Country = "USA"
            });
    });

这里可能涉及一些未记录的约定。这是有道理的:拥有的类型可以添加到更多的实体类中,EF 需要知道它是哪一个。有人会认为Id 应该就够了,毕竟b 中明确添加了类型,Organization。我认为这里有一些内部代码泄漏到公共 API 中,有一天这个故障可能会得到修复。

请注意,所有者 Id 的类型必须完全匹配,而类型本身的种子接受具有隐式转换的值。

【讨论】:

    【解决方案2】:

    如果您需要建立一对一关系,您需要添加 MyOrganization 的虚拟属性,并在播种数据时在邮政地址对象中添加 organizationId,这也有助于您配置一对一关系https://www.learnentityframeworkcore.com/configuration/one-to-one-relationship-configuration

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-26
      相关资源
      最近更新 更多