c# - EF Code First - 具有导航属性的多列索引

标签 c# entity-framework ef-code-first entity-framework-migrations ef-fluent-api

我想在多个列上放置索引(如 this question 中所述),但其中一个属性是模型中没有外键属性的导航属性。

TL;DR位于底部。


我的模型:

public class User
{
    public int Id { get; set; }
    public string Email { get; set; }
    public virtual Shop Shop { get; set; }
}

public class Shop
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Context : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Shop> Shops { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasRequired(u => u.Shop).WithMany();
        modelBuilder.Entity<User>().Property(u => u.Email).HasMaxLength(256);
    }
}

我使用扩展(基于提到的问题):

internal static class ModelBuilderExtensions
{
    public static StringPropertyConfiguration AddMultiColumnIndex(this StringPropertyConfiguration config, string indexName, int columnOrder, bool unique = false, bool clustered = false)
    {
        var indexAttribute = new IndexAttribute(indexName, columnOrder) { IsUnique = unique, IsClustered = clustered };
        var indexAnnotation = new IndexAnnotation(indexAttribute);

        return config.HasColumnAnnotation(IndexAnnotation.AnnotationName, indexAnnotation);
    }

    public static PrimitivePropertyConfiguration AddMultiColumnIndex(this PrimitivePropertyConfiguration property, string indexName, int columnOrder, bool unique = false, bool clustered = false)
    {
        var indexAttribute = new IndexAttribute(indexName, columnOrder) { IsUnique = unique, IsClustered = clustered };
        var indexAnnotation = new IndexAnnotation(indexAttribute);

        return property.HasColumnAnnotation(IndexAnnotation.AnnotationName, indexAnnotation);
    }
}

我希望创建一个索引,如下所示:

modelBuilder.Entity<User>().Property(x => x.Email).AddMultiColumnIndex("UX_User_EmailShopId", 0, unique: true);
modelBuilder.Entity<User>().Property(x => x.Shop.Id).AddMultiColumnIndex("UX_User_EmailShopId", 1, unique: true);

但这在构建迁移时给我一个错误:

System.InvalidOperationException: The type 'Shop' has already been configured as an entity type. It cannot be reconfigured as a complex type.

当我尝试按如下方式添加索引时,它会出现另一个错误:

modelBuilder.Entity<User>().Property(x => x.Shop).AddMultiColumnIndex("UX_User_EmailShopId", 1, unique: true);

The type 'My.NameSpace.Shop' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Data.Entity.ModelConfiguration.Configuration.StructuralTypeConfiguration.Property(System.Linq.Expressions.Expression>)


TL;DR

所以我的问题是,当我的模型中未定义 shop_id(并且我不想定义它)时,如何在电子邮件和商店 (id) 组合上使用 Fluent-api 添加索引?

生成的 SQL 应类似于:

CREATE UNIQUE NONCLUSTERED INDEX [UX_User_EmailShopId] ON [dbo].[User]
(
    [Email] ASC,
    [Shop_Id] ASC
)

最佳答案

TL&DR:如果您想在 FLUENT Pattern 中拥有多个索引,您可以执行以下操作:

You can now (EF core 2.1) use the fluent API as follows:

modelBuilder.Entity<ClassName>()
            .HasIndex(a => new { a.Column1, a.Column2});

关于c# - EF Code First - 具有导航属性的多列索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37726732/

相关文章:

.net - Entity Framework 4.1中的外键

c# - 如何在 Xamarin.Forms 中实现 INotifyPropertyChanged

c# - 从代码中使用 EntityFramework 重构数据库

c# - orderby 无法使用 LINQ 获取子查询中的前 1 个结果

entity-framework - 在我的EF实现通用存储库中找不到.Include()方法

c# - 是否可以在插入/更新之前在 POCO 中执行操作?

entity-framework - 多对多关系检测变化

c# - 与.net core和身份框架的集成测试

c# - 无法对隐藏控件执行 'Click'

c# - 如何搜索除id之外的其他字段