如何解决播种数据 - 没有 ID 的拥有类型
我有一个描述组织的实体,包括其邮政地址。地址存储在一个属性 (PostalAddress
) 中,组织的所有属性都存储在同一个数据库表中并进行展平。配置编译并应用迁移没有任何问题 - 如果我不播种数据。我已经在 Razor Pages 中测试了标准 CRUD - 没问题。
在 OnModelCreating
中添加种子时,编译时出现错误。
无法添加实体类型“Organization.PostalAddress#PostalAddress”的种子实体,因为没有为所需的属性“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
。我认为一些内部代码泄漏到这里的公共 API 中,有一天这个故障可能会被修复。
请注意,所有者 Id 的类型必须完全匹配,而类型本身的种子接受一个具有隐式转换的值。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。