如何在实体框架中使用TagWith() 6.我在Entity Framework Core 中阅读了很多关于TagWith() 的帖子。但他们都没有提供有关非核心实体框架的信息
我的主要需求是使用 EF 为生成的 SQL 查询添加一些注释。
var list = await _context.Tweets
.TagWith("GetTweets")<<---------------------------------------comment
.ToListAsync(cancellationToken)
.ConfigureAwait(false);
有一个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 行。)