如何在拥有的EF实体的属性上配置外键? [英] How to configure a foreign key on an owned EF entity's property?

查看:71
本文介绍了如何在拥有的EF实体的属性上配置外键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

EF Core 3.0

我在域中具有以下(简化的)实体:

I have the following (simplified) entities in my domain:

class ApplicationUser {
    public int Id { get; set; }
    public string UserName { get; set; }
    // other properties
}

[Owned]
class Stamp {
    public string Username { get; set; }
    public ApplicationUser User { get; set; }
    DateTime DateTime { get; set; }
}

class Activity {
    public Stamp Created { get; set; }
    public Stamp Modified { get; set; }
    // other properties
}

这不是特别相关,但是值得一提的是 ApplicationUser.UserName 是非主键,唯一键.( ApplicationUser 实际上是从ASP.NET IdentityUser 继承的.)

It's not particularly relevant, but it's worth mentioning that ApplicationUser.UserName is a non-primary, unique key. (ApplicationUser actually inherits from ASP.NET IdentityUser.)

我要强制说 Stamp.Username 是引用 ApplicationUser.UserName 的外键.

I want to enforce that Stamp.Username is a foreign key referencing ApplicationUser.UserName.

如果 Stamp 是常规的非所有实体,则可以建立这种关系:

If Stamp was a regular, non-owned entity, this would have set up that relationship:

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

    // Stamp.Username => ApplicationUser.UserName
    modelBuilder.Entity<Stamp>(e => {
        e.HasOne(s => s.User)
        .WithOne()
        .HasForeignKey<Stamp>(s => s.Username)
        .HasPrincipalKey<ApplicationUser>(u => u.UserName);
    });
    ...
}

当我尝试创建迁移( dotnet ef迁移添加)时,我收到一个 InvalidOperationException ,其中说无法将'Stamp'类型配置为非所有者,因为具有相同名称的拥有实体类型已经存在".

When I try to create a migration (dotnet ef migrations add) I get an InvalidOperationException saying "The type 'Stamp' cannot be configured as non-owned because an owned entity type with the same name already exists".

如何使用Fluent API或其他方式实现我想做的事情?

How to achieve what I'm trying to do, using Fluent API or otherwise?

推荐答案

这是一种可能的解决方案,可能不是最优雅的解决方案.它基于此答案ChW在评论中提到了.

This is one possible solution, likely not the most ellegant one. It is based on this answer mentioned by ChW in the comments.

modelBuilder.Entity<Activity>(e => {
    e.OwnsOne(a => a.Created)
    .HasOne<ApplicationUser>()
    .WithOne()
    .HasForeignKey<Stamp>(s => s.Username)
    .HasPrincipalKey<ApplicationUser>(u => u.UserName);
});

这将为特定所有者实体( Activity )的特定 Stamp 出现次数( Created )设置必需的外键.

This sets up the required foreign key on a particular Stamp occurence (Created) for a particular owner entity (Activity).

显然,对于其他每个 事件(在本例中为 Modified )和所有其他所有者实体(活动可能不是唯一的).

A similar block of code would obviously need to be repeated for every other Stamp occurence (in this example, Modified) and for every other owner entity (Activity may not be the only one).

顺便说一句,我也最终删除了 Stamp.User 导航属性,因为EF一直在使用它来自动创建另一个(不必要地)指向 ApplicationUser.Id <的外键./code>属性.

Btw, I also ended up removing the Stamp.User navigation property because EF has been using it to automatically create another foreign key that was (unwantedly) pointing to the ApplicationUser.Id property.

这篇关于如何在拥有的EF实体的属性上配置外键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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