播种数据 - 没有 Id 的自有类型
Seeding Data - Owned Type without Id
我有一个描述组织的实体,包括其邮政地址。地址存储在 属性 (PostalAddress
) 中,组织的所有属性存储并展平在同一数据库 table 中。配置编译和迁移应用没有任何问题 - 如果我不播种数据。我已经在 Razor Pages 中测试了标准的 CRUD - 没问题。
在 OnModelCreating
中添加种子时,编译时出现错误。
The seed entity for entity type 'Organization.PostalAddress#PostalAddress' cannot be added because no value was provided for the required property 'OrganizationId'.
这条消息让我感到困惑,因为 Organization
和 PostalAddress
都没有 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 这也有助于你配置一对一关系https://www.learnentityframeworkcore.com/configuration/one-to-one-relationship-configuration
异常消息是神秘的,但很有帮助。当您将 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
。我 认为 一些内部代码泄漏到 public API 这里,总有一天这个故障可能会被修复。
请注意,所有者 ID 的类型必须完全匹配,而类型本身的种子接受具有隐式转换的值。
我有一个描述组织的实体,包括其邮政地址。地址存储在 属性 (PostalAddress
) 中,组织的所有属性存储并展平在同一数据库 table 中。配置编译和迁移应用没有任何问题 - 如果我不播种数据。我已经在 Razor Pages 中测试了标准的 CRUD - 没问题。
在 OnModelCreating
中添加种子时,编译时出现错误。
The seed entity for entity type 'Organization.PostalAddress#PostalAddress' cannot be added because no value was provided for the required property 'OrganizationId'.
这条消息让我感到困惑,因为 Organization
和 PostalAddress
都没有 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 这也有助于你配置一对一关系https://www.learnentityframeworkcore.com/configuration/one-to-one-relationship-configuration
异常消息是神秘的,但很有帮助。当您将 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
。我 认为 一些内部代码泄漏到 public API 这里,总有一天这个故障可能会被修复。
请注意,所有者 ID 的类型必须完全匹配,而类型本身的种子接受具有隐式转换的值。