我正在将实体框架核心用于SQL Server和PostgreSQL。
我需要用包含列覆盖创建索引。
我使用NpgsqlMigrationsAnnotationProvider和NpgsqlMigrationsSqlGenerator来做到这一点。
我的代码是
NpgsqlMigrationsSqlGenerator
生成函数:
base.Generate(operation, model, builder, false);
System.Diagnostics.Debugger.Launch();
var includeIndexAnnotation = operation.FindAnnotation("IncludeIndex");
if (includeIndexAnnotation != null)
{
var includeColumns = includeIndexAnnotation.Value.ToString().Split(",");
var includeOperation = new StringBuilder();
builder.Append(" INCLUDE(");
foreach (var includeColumn in includeColumns)
{
if (includeOperation.Length > 0)
includeOperation.Append(",");
includeOperation.Append($"\"{includeColumn}\"");
}
includeOperation.Append(")");
builder.Append(includeOperation);
}
if (terminate)
{
builder.AppendLine(StatementTerminator);
EndStatement(builder);
}
和
NpgsqlMigrationsAnnotationProvider
For(IIndex index)函数:
var baseAnnotations = base.For(index);
var customAnnotations = index.GetAnnotations().Where(a => a.Name == "IncludeIndex");
return baseAnnotations.Concat(customAnnotations);
扩展名:
public static IndexBuilder Include<TEntity>(this IndexBuilder indexBuilder, Expression<Func<TEntity, object>> indexExpression)
{
var includeStatement = new StringBuilder();
foreach (var column in indexExpression.GetPropertyAccessList())
{
if (includeStatement.Length > 0)
includeStatement.Append(",");
includeStatement.AppendFormat("{0}", column.Name);
}
indexBuilder.HasAnnotation("IncludeIndex", includeStatement.ToString());
return indexBuilder;
}
DesignTimeDbContextFactory:
builder.ReplaceService<IMigrationsAnnotationProvider, PostgreSql.DbMigrationsAnnotationProvider>();
builder.ReplaceService<IMigrationsSqlGenerator, PostgreSql.DbMigrationsSqlGenerator>();
DbContext:
entity.HasIndex(log => new { log.Id }).Include<Log>(log => new { log.Type, log.Source, log.Created, log.Message })
此代码可与sql server正常工作,但不适用于postgresql。 无法将包含命令添加到CreateIndex查询。 感谢您的支持。