使用EF Core 2.2在SQL中为地理数据类型添加索引

时间:2018-12-23 16:44:28

标签: c# .net entity-framework-core

我首先使用EF Core 2.2代码创建一个具有NTS Point属性的表。效果很好,并在SQL中使用“地理位置”数据类型创建了一个表。现在,我想先从代码中索引该列。我只是在做一个基本的事情:

entity.HasIndex(x => x.Point);

我收到以下错误:

  

消息:System.Data.SqlClient.SqlException:表'TableName'中的列'PointColumnName'的类型无效,无法用作索引或统计信息中的键列。

有没有一种方法可以先使用代码在此列上添加索引?

1 个答案:

答案 0 :(得分:1)

最简单的方法是根据需要自定义迁移脚本。例如:

migrationBuilder.Sql(
@"
    UPDATE Customer
    SET Name = FirstName + ' ' + LastName;
");

或者您可以使用更全面的方法Custom Migration Operations

class MyMigrationsSqlGenerator : SqlServerMigrationsSqlGenerator
{
    public MyMigrationsSqlGenerator(
        MigrationsSqlGeneratorDependencies dependencies,
        IMigrationsAnnotationProvider migrationsAnnotations)
        : base(dependencies, migrationsAnnotations)
    {
    }

    protected override void Generate(
        MigrationOperation operation,
        IModel model,
        MigrationCommandListBuilder builder)
    {
        if (operation is CreateSpatialIndexOperation createSpatialIndexOperation)
        {
            Generate(createSpatialIndexOperation, builder);
        }
        else
        {
            base.Generate(operation, model, builder);
        }
    }

    private void Generate(
        CreateSpatialIndexOperation operation,
        MigrationCommandListBuilder builder)
    {
        var sqlHelper = Dependencies.SqlGenerationHelper;
        var stringMapping = Dependencies.TypeMappingSource.FindMapping(typeof(string));

        builder
            .Append("CREATE INDEX ")
            .Append(sqlHelper.DelimitIdentifier(operation.Name))
            ...
            .Append(stringMapping.GenerateSqlLiteral(...))
            .AppendLine(sqlHelper.StatementTerminator)
            .EndCommand();
    }
}

然后像使用它

 protected override void OnConfiguring(DbContextOptionsBuilder options)
   => options
        .UseSqlServer(connectionString)
        .ReplaceService<IMigrationsSqlGenerator, MyMigrationsSqlGenerator>();