我一直怀着极大的兴趣converstaion这里:的Linq:动态查询敷设渠道:查询移动到客户端
Construct Query with Linq rather than SQL strings
与关于构建表达式树,甚至表名是动态的。
为了实现这一目标,我创建了一个扩展方法,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语句,而不是确定客户端
感谢您花时间阅读本文,我欢迎您提出任何意见,解决方案,链接等,这可以帮助我。当然,如果我通过其他方式找到解决方案,我会在这里发布答案。
干杯。
你在那里有'Compile'的事实应该有一个大的红色标志来表明它不能在数据库服务器上运行。 – Gabe 2010-09-23 20:46:16