EF Core忽略导航属性

4
我有一个实体“User”,有两个属性“CreatedBy”和“UpdatedBy”,它们都引用了“User”。默认情况下,EF假定这两个属性是彼此的一对一关系。我收到以下错误信息:

消息:System.InvalidOperationException:无法确定‘User.CreatedBy’和‘User.UpdatedBy’之间被依赖的一对一关系中哪一边是子/从属端。要识别关系的子/从属端,请配置外键属性。如果这些导航不应该成为同一关系的一部分,请在不指定逆变换的情况下进行配置。请参阅http://go.microsoft.com/fwlink/?LinkId=724062获取更多详细信息。

目前,我的代码如下:
public class User
{

    public int Id { get; set; }

    public int? CreatedById { get; set; }
    public User CreatedBy { get; set; }

    public int? UpdatedById { get; set; }
    public User UpdatedBy { get; set; }

}

基本上,这是我正在尝试的:

  • 创建和更新之间没有关系(不需要导航/反向属性)
  • 任何数量的用户都可以拥有相同的 CreatedBy,并且任何数量的用户都可以拥有相同的 UpdatedBy

我如何要求 EF 忽略导航属性?我有 CreatedBy 的主要原因是我可以在以后使用 Include(u => u.CreatedBy)。我知道使用 IEnumerable<User> AllCreatedUsers 属性可以解决这个问题,但我不想为实体中的每个属性创建一个 IEnumerable。是否有一种使用 Fluent API 来解决这个问题的方法?

以下是我的尝试:

modelBuilder.Entity<User>()
                .Property<IEnumerable<User>>("AllCreatedUsers");

modelBuilder.Entity<User>().HasOne(u => u.CreatedBy)
                                .WithMany(u => EF.Property<IEnumerable<User>>(u, "AllCreatedUsers"));

尝试在“UpdatedBy”和“CreatedBy”上使用“ForeignKey”数据注释。 - Vivek Nuna
为什么您希望在添加导航属性时,EF忽略它,以便您拥有一个用于EF的导航属性? - Progman
@viveknuna 是的..我已经尝试过在注释和流畅API中使用ForeignKey - Neville Nazerane
@Progman 考虑到我永远不会使用这样的 IEnumerable,在一个类中拥有如此多未使用的属性是没有意义的。 - Neville Nazerane
@viveknuna 是的。再试了一次,ForeignKey 可以用了。上次可能只在一个属性上使用了 fk,但是现在在两个属性上都使用它就可以了。 - Neville Nazerane
2个回答

5

您需要使用不带参数的WithMany方法重载配置两个单一导航属性关系:

modelBuilder.Entity<User>()
    .HasOne(u => u.CreatedBy)
    .WithMany();

modelBuilder.Entity<User>()
    .HasOne(u => u.UpdatedBy)
    .WithMany(); 

我之前尝试过这个。我甚至试过复制粘贴你的代码。结果还是一样的。 - Neville Nazerane
我只能说这是处理这种模型的方法。如果您创建一个干净的新项目,从问题中复制/粘贴“User”类和答案中的流畅配置,您会发现它可以工作。 - Ivan Stoev
是的,我刚测试了一下,在一个干净的项目中它可以正常工作。然而,可能有一些特殊情况没有考虑到。@vivek的代码似乎在两种情况下都可以工作。 - Neville Nazerane
这对我来说毫无意义。FK与此问题真的无关(如果它们不符合约定,我可以在流畅的设置中包含它们),而数据注释在EF Core中绝对是不必要的(我会说已经过时了)。 - Ivan Stoev

3

您需要在这两个属性上使用ForeignKey数据注释。

public class User
{
    public int Id { get; set; }

    public int? CreatedById { get; set; }
    [ForeignKey("CreatedById")]
    public User CreatedBy { get; set; }

    public int? UpdatedById { get; set; }
    [ForeignKey("UpdatedById")]
    public User UpdatedBy { get; set; }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接