c# - 拥有自有属性(property)的种子实体

标签 c# entity-framework-core ef-core-2.1

我正在尝试在我的数据库中植入一个用户实体。 User 实体有一个 owend 属性 EmailPermissions

当我运行命令时

dotnet ef migrations add Initial;

我得到了错误

The seed entity for entity type 'User' cannot be added because it has the navigation 'EmailPermissions' set. To seed relationships you need to add the related entity seed to 'EmailPermissions' and specify the foreign key values {'UserId'}.

但是由于 EmailPermissions 是一个拥有的实体,我没有给它一个明确的 UserId 属性,这意味着我不能在数据库中单独播种它。

实体

public sealed class User : IdentityUser
{
    public User()
    {
        EmailPermissions = new EmailPermissions();
    }

    /* [..] */

    public string TemporaryEmailBeforeChange { get; set; }
    public bool IsEmailAwaitingUpdate { get; set; }
    public EmailPermissions EmailPermissions { get; set; }
    public ICollection<Registeration> Registerations { get; set; }

    /* [..] */

}

[Owned]
public class EmailPermissions
{
    /* [..] */

    public bool Newsletter { get; set; }
    public bool PromotionalOffers { get; set; }
    public bool PrestationReminders { get; set; }
    public bool PrestationOffers { get; set; }
}

播种电话

private void SeedUser(ModelBuilder builder)
{
    builder.Entity<User>().HasData(
        new User
        {
            Id = "37846734-172e-4149-8cec-6f43d1eb3f60",
            Email = "foo@foo.foo",
            UserName = "foo@foo.foo",
            PasswordHash = "AQAAAAEAACcQAAAAEIytBES+jqKH9jfuY3wzKyduDZruyHMGE6P+ODe1pSKM7BuGjd3AIe6RGRHrXidRsg==",
            SecurityStamp = "WR6VVAGISJYOZQ3W7LGB53EGNXCWB5MS",
            ConcurrencyStamp = "c470e139-5880-4002-8844-ed72ba7b4b80",
            EmailConfirmed = true
        });
}   

如果我从构造函数中删除 EmailPermissions 属性的实例化,则会出现以下错误

The entity of type 'User' is sharing the table 'AspNetUsers' with entities of type 'EmailPermissions', but there is no entity of this type with the same key value that has been marked as 'Added'.

当用户具有自有属性时,如何通过 .HasData 方法为用户播种?

最佳答案

目前文档中缺少此信息(由 #710: Document how to seed owned types 跟踪)。 EF Core 团队(通过示例)在 #12004: Problem seeding data that contains owned type 中对其进行了解释主题:

Owned types must be seeded with a HasData call after the OwnsOne call. Also, since owned types by convention have a primary key generated in shadow state, and since seed data requires keys to be defined, then this requires use of an anonymous type and setting the key.

这基本上就是异常消息告诉您的内容。

按照建议,您应该从构造函数中删除 EmailPermissions 属性的实例化,并添加如下种子代码:

builder.Entity<User>().OwnsOne(e => e.EmailPermissions).HasData(
    new
    {
        UserId = "37846734-172e-4149-8cec-6f43d1eb3f60",
        // other properties ...
    }
);

由于需要知道影子 PK 名称和匿名类型的使用,这非常烦人且容易出错。正如同一位成员提到的

Note that this would become easier if navigations were supported for seeding, which is tracked by #10000: Data Seeding: Add support for navigations

关于c# - 拥有自有属性(property)的种子实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50862525/

相关文章:

c# - 四指阵法统一

c# - 在 C# webBrowser 控件中调用 Javascript 函数

c# - EF Core ChangeTracker() 当前值和原始值对于修改后的实体是相同的

c# - Entity Framework 7 DbContext 脚手架

c# - EF Core 2.1.4 FileLoadException System.ComponentModel.Annotations 4.2.0.0

c# - 带有 DBQuery 的 Entity Framework Core 2 - 获取对象引用未设置到对象的实例

c# - 如何获取属性的TypeConverter

c# - 如何在调用同一类中的另一个方法的单元测试中使用 Moq

c# - ASP.NET Core 5 Blazor WASM、gRPC、Entity Framework Core 5 : many-to-many results in stack overflow