我有以下两个类
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不喜欢我在索引中使用引用属性这一事实。我该如何解决这个问题?
答案 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();
}