EF Core - 索引中的导航属性

10
我有以下两个类:
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文档,没有数据注释语法,因此我使用流畅的语法:

    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 database update System.InvalidOperationException: 因为它被配置为导航属性,所以无法为实体类型“Tip”上的属性“Tipster”调用Property。Property只能用于配置标量属性。

看起来EF不喜欢我在索引中使用引用属性。我该如何修复?
3个回答

8
您不能在索引定义表达式中使用导航属性。相反,应该使用相应的FK属性。
在您的情况下问题在于您的模型Tip中没有显式的FK属性。按照惯例,EF Core会创建int?TipsterId影子属性。因此,理论上您应该能够使用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))

救命之答案!谢谢。 - mahdi mahzouni

4

您必须显式定义属性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();
}

2
我正在点赞这个答案。对我来说,明确定义阴影属性并使用它更有意义。 - ktravelet

1
您定义实体EF的方式将引用列放入tipster表中,因为它看起来像是1-n关系。这意味着Tipster可以发布多个提示,但每个提示只能由单个Tipster发布。
这意味着在数据库层面上没有任何需要索引的内容。没有列,没有键-什么都没有。
要解决此问题,您可能会问自己首先想要通过索引实现什么目标。索引应该使使用索引列的查询更快,并避免全表扫描。

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