How to configure a foreign key on an owned EF entity's property?

不打扰是莪最后的温柔 提交于 2021-01-29 12:54:31

问题


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
}

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.)

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

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);
    });
    ...
}

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".

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


回答1:


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);
});

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

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).

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.



来源:https://stackoverflow.com/questions/58199833/how-to-configure-a-foreign-key-on-an-owned-ef-entitys-property

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!