EF Core-索引中的导航属性

Dim*_*nev 6 c# ef-core-2.0

我有以下两节课

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; }
}
Run Code Online (Sandbox Code Playgroud)

现在,我想在“提示”表中创建唯一索引。根据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();
    }
Run Code Online (Sandbox Code Playgroud)

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

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

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

Iva*_*oev 5

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

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

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

不幸的是,这目前不起作用(EF Core 2.0.1)。所以你必须求助于HasIndex重载params string[] propertyNames

.HasIndex("TipsterId", nameof(Tip.Home), nameof(Tip.Away), nameof(Tip.Prediction))
Run Code Online (Sandbox Code Playgroud)


Tox*_*ron 1

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

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

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