由于名称,EF Core 将 属性 误认为是 PK

EF Core mistaking property as PK because of name

我有一个名为 User 的实体和一个名为 UserRef 的包含 UserId 的值对象。

EF 正在获取 UserRef 上的 UserId 并尝试将其映射到用户。

这不是为 DDD 而设计的,我没有兴趣将它用作导航 属性。

如果我将 UserRef 属性 重命名为 User_Id,一切正常。

我如何告诉 EF 不理会 属性,并停止尝试对它做任何事情(read/write 它的值除外)?

public class User
{
    public Guid Id { get; private set; }

    public UserRef? ArchivedByUser { get; private set; }
}

public class UserRef
{
    public Guid UserId { get; private set; }
}

public class UserConfiguration : IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        builder.HasKey(o => o.Id);

        builder.OwnsOne(o => o.ArchivedByUser, archivedByUser => {
            archivedByUser.Property(userRef => userRef.UserId)
                            .HasColumnName("ArchivedByUser");
        });

    }
}

我收到以下错误:

The keys {'UserId'} on 'User.ArchivedByUser#UserRef' and {'Id'} on 'User' are both mapped to 'User.PK_User' but with different columns ({'ArchivedByUser'} and {'Id'}).

谢谢!

拥有的实体有 implicit key(与所有者共享 PK/FK 的 one-to-one 关系),按照惯例是名为 <owner entity name><owner entity key name> 的影子 属性。

在这种特殊情况下是 UserId 并与具有相同名称和类型的 class 属性 匹配,因此 EF 决定将其用于上述目的。

当 EF 约定不起作用时,您通常会求助于显式配置。在这种情况下,指定要用作 PK/FK 的不同影子 属性 名称就足够了。例如

archivedByUser.WithOwner().HasForeignKey("OwnerId");

该名称是任意的,因为没有与之关联的 table 列。

以上流畅的API调用就可以达到目的了。但是如果你想绝对 sure/maximum 显式,那么完整的配置就像

const string KeyPropertyName = "OwnerId";
archivedByUser.Property<Guid>(KeyPropertyName);
archivedByUser.HasKey(KeyPropertyName);
archivedByUser.WithOwner().HasForeignKey(KeyPropertyName);