关于 c#:.NET Core 3 / EF.Core 3:`QueryModelGenerator`、`RelationalQueryModelVisitor` 等发生了什么

 2022-01-07 

.NET Core 3 / EF.Core 3: what happened to `QueryModelGenerator`, `RelationalQueryModelVisitor` and etc

我想知道发生了什么:QueryModelGeneratorRelationalQueryModelVisitorqueryCompilationContext.CreateQuerymodelVisitor() 似乎都消失了。

我有以下代码,但我无法尝试将其从 2.2 转换为 .NET Core 3

1
2
3
4
5
6
7
8
9
10
11
public static string ToSql<TEntity>(this IQueryable<TEntity> query, DbContext dbCtx)
{
    var modelGenerator = dbCtx.GetService<IQueryModelGenerator>();
    var queryModel = modelGenerator.ParseQuery(query.Expression);
    var databaseDependencies = dbCtx.GetService<DatabaseDependencies>();
    var queryCompilationContext = databaseDependencies.QueryCompilationContextFactory.Create(false);
    var modelVisitor = (RelationalQueryModelVisitor) queryCompilationContext.CreateQueryModelVisitor();
    modelVisitor.CreateQueryExecutor<TEntity>(queryModel);
    var sql = modelVisitor.Queries.FirstOrDefault()?.ToString();
    return sql;
}


在 EF 3 中不再支持。

这里是现在怎么做

1
2
3
4
5
6
7
8
9
10
11
12
13
    public static string ToSql<TEntity>(this IQueryable<TEntity> query)
    {
        var enumerator = query.Provider.Execute<IEnumerable<TEntity>>(query.Expression).GetEnumerator();
        var enumeratorType = enumerator.GetType();
        var selectFieldInfo = enumeratorType.GetField("_selectExpression", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException($"cannot find field _selectExpression on type {enumeratorType.Name}");
        var sqlGeneratorFieldInfo = enumeratorType.GetField("_querySqlGeneratorFactory", BindingFlags.NonPublic | BindingFlags.Instance) ?? throw new InvalidOperationException($"cannot find field _querySqlGeneratorFactory on type {enumeratorType.Name}");
        var selectExpression = selectFieldInfo.GetValue(enumerator) as SelectExpression ?? throw new InvalidOperationException($"could not get SelectExpression");
        var factory = sqlGeneratorFieldInfo.GetValue(enumerator) as IQuerySqlGeneratorFactory ?? throw new InvalidOperationException($"could not get IQuerySqlGeneratorFactory");
        var sqlGenerator = factory.Create();
        var command = sqlGenerator.GetCommand(selectExpression);
        var sql = command.CommandText;
        return sql;
    }

在此处查看更多信息:
https://stackoverflow.com/a/51583047/196698
https://gist.github.com/rionmonster/2c59f449e67edf8cd6164e9fe66c545a#gistcomment-3059688