如何使用 Entity Framework Core 2.1 定义多字段索引

问题描述 投票:0回答:2

我正在使用 ASP.Net Core 2.1 API,我使用 Entity Framework Core 2.1。我正在使用迁移来管理对数据库的更改。我的后备数据存储是 Azure SQL Server 的一个实例。

我需要在我的一个表中添加一个多字段非聚集索引,但我很难在我的谷歌搜索中找到关于如何执行此操作的简明参考。

我尝试在 POCO 类中使用 [Index()] 数据注释,但无法识别。因此,我假设我必须在我的 DbContext 类的 OnModelCreating 方法中执行此操作,但我还没有找到如何为多字段非聚集索引执行此操作的示例。

这里是一个示例实体类

public class H1Record : EntityBase
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    [ForeignKey("ShippingServicesFileId")]
    public ShippingServicesFile ShippingServicesFile { get; set; }

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

    [Column(TypeName = "varchar(20)")]
    public string BatchId { get; set; }

    [Column(TypeName = "varchar(34)")]
    [MaxLength(34)]
    public string ElectronicFileNumber { get; set; }

    [Column(TypeName = "varchar(1)")]
    [MaxLength(1)]
    public string ElectronicFileType { get; set; }

    [Column(TypeName = "varchar(8)")]
    [MaxLength(8)]
    public string DateOfMailing { get; set; }

    [Column(TypeName = "varchar(6)")]
    [MaxLength(6)]
    public string TimeOfMailing { get; set; }

    public DateTime MailingDateTime { get; set; }

    [Column(TypeName = "varchar(1)")]
    [MaxLength(1)]
    public string EntryFacilityType { get; set; }

    [Column(TypeName = "varchar(5)")]
    [MaxLength(5)]
    public string EntryFacilityZipCode { get; set; }

    [Column(TypeName = "varchar(4)")]
    [MaxLength(4)]
    public string EntryFacilityZipPlus4 { get; set; }

    [Column(TypeName = "varchar(2)")]
    [MaxLength(2)]
    public string DirectEntryOriginCountryCode { get; set; }

    [Column(TypeName = "varchar(3)")]
    [MaxLength(3)]
    public string ShipmentFeeCode { get; set; }

    [Column(TypeName = "varchar(6)")]
    [MaxLength(6)]
    public string ExtraFeeForShipment { get; set; }

    [Column(TypeName = "varchar(2)")]
    [MaxLength(2)]
    public string ContainerizationIndicator { get; set; }

    [Column(TypeName = "varchar(3)")]
    [MaxLength(3)]
    public string UspsElectronicFileVersionNumber { get; set; }

    [Column(TypeName = "varchar(12)")]
    [MaxLength(12)]
    public string TransactionId { get; set; }

    [Column(TypeName = "varchar(8)")]
    [MaxLength(8)]
    public string SoftwareVendorProductVersionNumber { get; set; }

    [Column(TypeName = "varchar(9)")]
    [MaxLength(9)]
    public string FileRecordCount { get; set; }

    [Column(TypeName = "varchar(9)")]
    [MaxLength(9)]
    public string MailerId { get; set; }

    public ICollection<D1Record> D1Records { get; set; } = new List<D1Record>();

    public ICollection<C1Record> C1Records { get; set; } = new List<C1Record>();

}

这是实体基类

public class EntityBase
{
    public DateTime CreatedDate { get; set; }
    public DateTime LastModifiedDate { get; set; }
    public int CreatedByUserId { get; set; }
    public int LastModifiedByUserId { get; set; }
    public bool DeleteFlag { get; set; }

}

我想在我的 DbContext 的 OnModelCreating 方法中为 ShippingServicesFileId 和 DeleteFlag 创建一个非聚集索引,当我在我的包管理器控制台中运行添加迁移时它会被拾取。

有什么想法吗?

c# sql-server .net-core entity-framework-core asp.net-core-2.0
2个回答
8
投票

更新(适用于 EF Core >= 5):

从 EF Core 5.0 开始,还可以使用数据注释在多列上定义复合索引:

[Index(nameof([Column1]), nameof([Column2], ...))]
public class ...
{
    ...
}

使用

[Index(nameof([Column1]), nameof([Column2], ..., IsUnique = true))]

创造独一无二的。

注意:.ForSqlServerIsClustered() 不能写成数据注解(SQL Server 上的聚集索引)。在这里你应该继续使用 Fluent API(见下文)。

https://learn.microsoft.com/en-us/ef/core/modeling/indexes?tabs=data-annotations

更新(适用于 EF Core < 5):

您不能在多于一个带有数据注释的列上创建索引,因此您必须使用 Fluent API(在 OnModelCreating 中):

modeBuilder.Entity<ENTITYCLASS>().HasIndex(x => new {x.PROPERTY1, x.PROPERTY2, ...})

创建非聚集索引。使用 .IsUnique() 创建一个唯一的。如果你想在 SQL Server 上使用聚集索引,请使用 .ForSqlServerIsClustered() 。 您可以选择使用 .HasName("...").

给它另一个名字

0
投票

如果这是您的首选方法,您可以在迁移期间将列作为字符串数组传入。例如

migrationBuilder.CreateIndex("IX_H1Record", "H1Record",new string[] { "ShippingServicesFileId", "DeleteFlag"}, "dbo");
© www.soinside.com 2019 - 2024. All rights reserved.