我一直非常感兴趣地关注这里的对话:
关于构建即使表名也是动态的表达式树。
为此,我创建了一个扩展方法 addWhere,如下所示:
static public IQueryable<TResult> addWhere<TResult>(this IQueryable<TResult> query, string columnName, string value)
{
var providerType = query.Provider.GetType();
// Find the specific type parameter (the T in IQueryable<T>)
var iqueryableT = providerType.FindInterfaces((ty, obj) => ty.IsGenericType && ty.GetGenericTypeDefinition() == typeof(IQueryable<>), null).FirstOrDefault();
var tableType = iqueryableT.GetGenericArguments()[0];
var tableName = tableType.Name;
var tableParam = Expression.Parameter(tableType, tableName);
var columnExpression = Expression.Equal(
Expression.Property(tableParam, columnName),
Expression.Constant(value));
var predicate = Expression.Lambda(columnExpression, tableParam);
var function = (Func<TResult, Boolean>)predicate.Compile();
var whereRes = query.Where(function);
var newquery = whereRes.AsQueryable();
return newquery;
}
[感谢 Timwi 提供该代码的基础]
哪个在功能上有效。
我可以打电话:
query = query.addWhere("CurUnitType", "ML 15521.1");
它在功能上等同于:
query = query.Where(l => l.CurUnitType.Equals("ML 15521.1"));
即,返回的行是相同的。
但是,我开始查看 sql 日志,并注意到以下行:
query = query.Where(l => l.CurUnitType.Equals("ML 15521.1"));
生成的查询是:
SELECT (A bunch of columns)
FROM [dbo].[ObjCurLocView] AS [t0]
WHERE [t0].[CurUnitType] = @p0
而当我使用这条线时
query = query.addWhere("CurUnitType", "ML 15521.1");
生成的查询是:
SELECT (the same bunch of columns)
FROM [dbo].[ObjCurLocView] AS [t0]
因此,比较现在发生在客户端,而不是被添加到 sql 中。
显然,这不是那么热。
老实说,我主要是从 Timwi 的(略有不同的)示例中剪切并粘贴了 addWhere 代码,所以其中一些内容超出了我的想象。我想知道我是否可以对此代码进行任何调整,因此表达式被转换为 SQL 语句,而不是在客户端确定
感谢您花时间阅读本文,我欢迎任何可以帮助我的评论、解决方案、链接等。当然,如果我通过其他方式找到解决方案,我会在这里发布答案。
干杯。