简体   繁体   English

在带有外行键字段的代码优先迁移的Entity Framework 7中添加索引

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

I think this is going to be easy (famous last words) but I'm new to EF7 and the Code First concept in general and .Net 5 and EF7 is relatively new at this point as well so there's not much out there yet. 我认为这将很容易(著名的遗言),但是我对EF7和Code First概念还是陌生的,而.Net 5和EF7在这一点上还相对较新,因此目前尚不多。 I'm converting a project from old school ASP 2.0 to .Net 5 and I'm recreating the whole database structure so Code First Migrations is good choice for me here. 我正在将一个项目从旧版本的ASP 2.0转换为.Net 5,并且正在重新创建整个数据库结构,因此“代码优先迁移”对我来说是个不错的选择。

I have an AdvertisementHistory table that links back to an Advertisement table and for every Advertisement record there will be a record in the AdvertisementHistory table for every month of every year the ad is running. 我有一个AdvertisementHistory表,该表链接回到Advertisement表,对于每个广告记录,每年广告运行的每个月,AdvertisementHistory表中都会有一条记录。 I'm basically tracking Ad "Hit Counts" by month and year. 我基本上是按月份和年份跟踪广告的“点击计数”。 I want to put a unique index in AdvertisementHistory on "AdvertisementID, Year, Month" and I certainly know how to do this in SQL, but EF Code First is yelling at me the way that I'm doing: 我想在AdvertisementHistory中的“ AdvertisementID,Year,Month”上放置一个唯一索引,我当然知道如何在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();
    }
}

Then I break out the Command Window since we don't have a project console for .Net 5 EF7 yet: 然后我打开“命令窗口”,因为我们还没有.Net 5 EF7的项目控制台:

CMD> dnx ef migrations add Initial_FS CMD> dnx ef迁移添加Initial_FS

Here are the results: 结果如下:

{{....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'. 无法将属性“ Advertisement”添加到实体类型“ AdvertisementHistory”,因为在实体类型“ AdvertisementHistory”上已经存在具有相同名称的导航属性。

So if I remove "p.Advertisement" from my .HasIndex call everything works fine and it generates the code to make a proper index (although a bad one since I need the Ad ID). 因此,如果我从.HasIndex调用中删除“ p.Advertisement”,那么一切都会正常运行,并且它会生成代码以建立适当的索引(尽管由于我需要Ad ID,所以它是一个不好的索引)。 But it means this is definitely related to the fact them I'm using a field in my index that is a Foreign Key. 但这意味着,这肯定与我在索引中使用外键的字段有关。 I've tried a TON of different variations and annotations on the classes but nothing gets me a clean migration. 我在类上尝试了多种不同的变体和注释,但是没有任何东西可以使我顺利迁移。

As you can see I'm trying very hard to code this from a minimalist perspective and letting .Net "Do its thing" wherever I can. 如您所见,我正在努力从极简主义的角度对此进行编码,并让.Net尽我所能。 This is why I think I'm missing something very simple here since this is not an unusual concept. 这就是为什么我认为我在这里缺少非常简单的东西的原因,因为这不是一个不寻常的概念。

And in case you're wondering this (for the most part) is an initial migration since the only tables that currently exist in the database are the ones you get from AspNet.Identity. 而且,如果您想知道这(大多数情况下)是一次初始迁移,因为数据库中当前存在的唯一表就是您从AspNet.Identity获得的表。

Thanks in advanced community... 谢谢高级社区...

Try this. 尝试这个。 What you really want is to add a foreign key annotation for Advertisement and use this in your index: 您真正想要的是为广告添加外键注释,并在索引中使用它:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM