EF Core - 索引中的导航属性

时间:2017-12-21 14:42:03

标签: 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; }
}

现在,我想在theTip表中创建唯一索引。根据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:..&gt; dotnet ef数据库更新System.InvalidOperationException:   无法在实体类型'Tip'上为属性'Tipster'调用Property   因为它被配置为导航属性。物业只能   用于配置标量属性。

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

3 个答案:

答案 0 :(得分:1)

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

这意味着在数据库级别上没有索引。没有专栏,没有钥匙 - 没什么。

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

答案 1 :(得分:1)

您无法在索引定义表达式中使用导航属性。相反,您应该使用相应的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))

答案 2 :(得分:0)

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

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();
}