我有以下两节课
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不喜欢我在索引中使用引用属性的事实。我该如何解决?
您不能在索引定义表达式中使用导航属性。相反,您应该使用相应的 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)
您定义实体的方式 EF 会将引用列放入tipster 表中,因为它看起来像 1-n 关系。这意味着一个提示者可以放置多个提示,但每个提示只能由一个提示者放置。
这意味着在数据库级别上没有任何内容可以索引。没有列,没有键——什么都没有。
要解决这个问题,您可能首先会问自己真正想通过索引实现什么目标。索引应该使使用索引列的查询更快并避免全表扫描。