拥有财产的种子实体 [英] Seed entity with owned property

查看:80
本文介绍了拥有财产的种子实体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to seed an user entity in my database. The User entity has an owend property EmailPermissions.

当我运行命令


dotnet ef迁移时,请添加Initial;

dotnet ef migrations add Initial;

我收到错误


无法添加实体类型用户的种子实体,因为它具有导航 EmailPermissions的设置。要播种关系,您需要将相关的实体种子添加到'EmailPermissions'并指定外键值{'UserId'}。

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 属性,这意味着我无法播种

but since EmailPermissions is an owned entity I didn't give it an explicit UserId property, meaning I can't seed it separately in the database.

实体

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的实例属性,我得到了以下错误

If I remove the instantiation of the EmailPermissions property from the constructor I get the following error instead


类型'User'的实体共享表'AspNetUsers '具有类型为'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 方法为用户播种?

How can I seed a user via the .HasData method when it has an owned property ?

推荐答案

当前,文档中缺少此信息(由跟踪#710:记录如何播种拥有的类型)。 EF核心团队(在示例中)在#12004:播种包含拥有类型的数据时出现问题线程:

Currently this information is missing from the documentation (tracked by #710: Document how to seed owned types). It's explained by EF Core team (with example) in the #12004: Problem seeding data that contains owned type thread:


自有类型必须使用 HasData 调用作为种子 OwnsOne 调用。同样,由于按照惯例,拥有类型具有在影子状态下生成的主键,并且由于种子数据需要定义键,因此这需要使用匿名类型并设置键。

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.

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

which is basically what the exception message is telling you.

根据建议,您应该删除 EmailPermissions 属性,并添加如下代码:

Following the advice, you should remove the instantiation of the EmailPermissions property from the constructor and add a seeding code like this:

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

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

Quite annoying and error prone due to the need to know the shadow PK name and the usage of an anonymous type. As the same member mentioned


请注意,如果支持导航以进行播种,这将变得更加容易,该导航由#10000:数据播种:添加对导航的支持

这篇关于拥有财产的种子实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆