【问题标题】:EF Core - navigational property in indexEF Core - 索引中的导航属性
【发布时间】:2017-12-21 14:42:03
【问题描述】:

我有以下两个类

public class Tip
{
    public string Home { get; set; }
    public string Away { get; set; }
    public string Prediction { get; set; }
    public Tipster Tipster { get; set; }
    ... other properties
}


public class Tipster
{
    public int Id { get; set; }
    public string Username { get; set; }
    public string Platform { get; set; }
}

现在,我想在Tip 表中创建唯一索引。根据 EF Core 文档,没有 Data Annotations 语法,所以我使用的是流利的:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Tip>()
            .HasIndex(entity => new { entity.Tipster, entity.Home, entity.Away, entity.Prediction })
            .HasName("IX_UniqueTip")
            .IsUnique();
    }

现在,当我更新数据库时,出现以下错误

C:..>dotnet ef 数据库更新 System.InvalidOperationException: 无法在实体类型“提示”上调用属性“提示者”的属性 因为它被配置为导航属性。财产只能 用于配置标量属性。

似乎 EF 不喜欢我在索引中使用引用属性这一事实。我该如何解决?

【问题讨论】:

    标签: c# ef-core-2.0


    【解决方案1】:

    您必须明确定义属性 TipsterId 导致导航属性将其定义为阴影,因此您不能在自定义索引或备用键上使用它

    public class Tip
    {
        public string Home { get; set; }
        public string Away { get; set; }
        public string Prediction { get; set; }
    
        public int TipsterId { get; set; }
    
        public Tipster Tipster { get; set; }
        ... other properties
    }
    

    现在可以

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Tip>()
            .HasIndex(entity => new { entity.TipsterId, entity.Home, entity.Away, entity.Prediction })
            .HasName("IX_UniqueTip")
            .IsUnique();
    }
    

    【讨论】:

    • 我赞成这个答案。明确定义 shadow 属性并使用它对我来说更有意义
    【解决方案2】:

    您不能在索引定义表达式中使用导航属性。相反,您应该使用相应的 FK 属性。

    您的问题是您的模型Tip 中没有明确的 FK 属性。按照惯例,EF Core 将创建 int? TipsterId shadow property。所以理论上你应该可以使用EF.Property 方法来访问它:

    .HasIndex(e => new { TipsterId = EF.Property<int>(e, "TipsterId"), e.Home, e.Away, e.Prediction })
    

    很遗憾,目前这不起作用(EF Core 2.0.1)。所以你必须诉诸HasIndex 重载params string[] propertyNames:

    .HasIndex("TipsterId", nameof(Tip.Home), nameof(Tip.Away), nameof(Tip.Prediction))
    

    【讨论】:

    • 救命答案! tnx
    【解决方案3】:

    他们定义实体的方式 EF 会将引用列放入提示表中,因为它看起来像 1-n 关系。这意味着提示者可以放置多个提示,但每个提示只能由单个提示者放置。

    这意味着在数据库级别上没有可索引的内容。没有列,没有键 - 什么都没有。

    要解决这个问题,您可能首先要问自己,您真正想用索引实现什么。索引应该使用索引的列更快地进行查询并避免全表扫描。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-22
      • 2018-10-10
      • 2020-02-23
      • 2022-09-23
      • 1970-01-01
      • 2018-04-03
      • 2022-01-04
      相关资源
      最近更新 更多