实体框架中的 TagWith

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

如何在实体框架中使用TagWith() 6.我在Entity Framework Core 中阅读了很多关于TagWith() 的帖子。但他们都没有提供有关非核心实体框架的信息

我的主要需求是使用 EF 为生成的 SQL 查询添加一些注释。

var list = await _context.Tweets
    .TagWith("GetTweets")<<---------------------------------------comment 
    .ToListAsync(cancellationToken)
    .ConfigureAwait(false);
c# entity-framework
1个回答
0
投票

有一个nuget包来添加功能。

它使用了一个非常有趣的概念:它使用常量添加一个where子句,然后注册一个IDbCommandInterceptor来重写SQL,删除where子句并添加注释。

插件的唯一问题是在 TagWith 中,它添加的 where 子句默认为 false:

public static IQueryable<T> TagWith<T>(this IQueryable<T> query, string tag)
{
    // ...
    var tagConstant = Expression.Constant(TagMarker);
    var tagValue = Expression.Constant(tag);
    var equalsExpression = Expression.Equal(tagConstant, tagValue);
    var predicate = Expression.Lambda<Func<T, bool>>(
        equalsExpression, Expression.Parameter(typeof(T))
    );
    return query.Where(predicate);
}

这会生成以下 SQL:

WHERE ... AND (N'!__tag!' = N'My Comment') ...

因此,如果您使用 IQueryable 的

.ToString()
来获取 SQL,它不会通过命令拦截器运行,因此您会得到不返回任何记录的 where 子句。这也意味着,如果命令拦截器出现任何问题,SQL 将被发送到数据库引擎。哎呀!

在我自己的代码中,我决定修改它以使用

Expression.NotEqual
,这样表达式就是
N'!__tag!' <> N'My Comment'
,默认为真。

(实际上我什至不使用

IDbCommandInterceptor
,我只是将它留在 WHERE 子句中。更简单的代码,因为我只为那个扩展方法添加了大约 8 行。)

© www.soinside.com 2019 - 2024. All rights reserved.