在作为外键的字段上使用代码优先迁移在 Entity Framework 7 中添加索引

Adding an Index in Entity Framework 7 with Code First Migrations on a field that is a Foreign Key

我认为这会很容易(著名的遗言),但我对 EF7 和 Code First 概念一般来说是新手,而 .Net 5 和 EF7 在这一点上也相对较新,所以没有太多在那里。我正在将一个项目从旧学校 ASP 2.0 转换为 .Net 5,并且我正在重新创建整个数据库结构,因此 Code First Migrations 在这里对我来说是个不错的选择。

我有一个 AdvertisementHistory table 链接回一个 Advertisement table 并且对于每条 Advertisement 记录,每年每个月的 AdvertisementHistory table 中都会有一条记录广告是 运行。我基本上是按月和年跟踪 Ad "Hit Counts"。我想在 "AdvertisementID, Year, Month" 上的 AdvertisementHistory 中放置一个唯一索引,我当然知道如何在 SQL 中执行此操作,但 EF Code First 正以我的方式对我大喊大叫:

public class Advertisement
{
    public int ID { get; set; }

    [Required]
    public string ImageURL { get; set; }

    [Required]
    public string DestinationURL { get; set; }

    {{....Removing other fields you don't care about}}
}

public class AdvertisementHistory
{
    public int ID { get; set; }

    [Required]
    public Advertisement Advertisement { get; set; }

    [Required]
    public int Year { get; set; }

    [Required]
    public int Month { get; set; }

    [Required]
    public int Clicked { get; set; }

    {{....Removing other fields you don't care about}}
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public DbSet<Advertisement> Advertisements { get; set; }
    public DbSet<AdvertisementHistory> AdvertisementHistory { get; set; }
    {{....Removing other classes you don't care about}}

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<AdvertisementHistory>()
            .HasIndex(p => new { p.Advertisement, p.Year, p.Month })
            .IsUnique();
    }
}

然后我打开命令 Window 因为我们还没有 .Net 5 EF7 的项目控制台:

CMD> dnx ef migrations add Initial_FS

结果如下:

{{....A bunch of stuff gets generated properly}}

The property 'Advertisement' cannot be added to the entity type 'AdvertisementHistory' because a navigation property with the same name already exists on entity type 'AdvertisementHistory'.

因此,如果我从我的 .HasIndex 调用中删除 "p.Advertisement",则一切正常,并且它会生成代码以创建正确的索引(尽管因为我需要广告 ID,所以它很糟糕)。但这意味着这肯定与我在索引中使用的字段是外键这一事实有关。我在 类 上尝试了大量不同的变体和注释,但没有任何东西能让我进行干净的迁移。

如您所见,我正在非常努力地从极简主义的角度对此进行编码,并尽可能让 .Net "Do its thing" 发挥作用。这就是为什么我认为我在这里遗漏了一些非常简单的东西,因为这不是一个不寻常的概念。

如果您想知道这(大部分)是初始迁移,因为数据库中当前存在的唯一 table 是您从 AspNet.Identity 获得的那些。

感谢高级社区...

试试这个。您真正想要的是为 Advertisement 添加一个外键注释并在您的索引中使用它:

public class Advertisement
{
    public int ID { get; set; }
    [Required]
    public string ImageURL { get; set; }
    [Required]
    public string DestinationURL { get; set; }
}

public class AdvertisementHistory
{
    public int ID { get; set; }
    public int AdvertisementID { get; set; }
    [Required]
    [ForeignKey("AdvertisementID")]
    public Advertisement Advertisement { get; set; }
    [Required]
    public int Year { get; set; }
    [Required]
    public int Month { get; set; }
    [Required]
    public int Clicked { get; set; }
}

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<AdvertisementHistory>()
        .HasIndex(p => new { p.AdvertisementID, p.Year, p.Month })
}