我正在尝试扩展SqlMethods.Like方法以支持属性名称而不是属性值,我写了以下扩展方法:
public static bool Like(this object obj, string propertyName, string pattern)
{
var properties = obj.GetType().GetProperties().Select(p => p.Name);
if(!properties.Contains(propertyName))
throw new Exception(string.Format("Object does not contain property:{0}", propertyName));
return SqlMethods.Like(obj.GetType().GetProperty(propertyName).GetValue(obj, null).ToString(), pattern);
}
但是,该方法引发以下异常:方法“Boolean Like(System.Object,System.String,System.String)”不支持到SQL的转换。
如何编写支持SQL事务的扩展方法?
发布于 2010-07-29 14:44:46
我从RichardD那里找到了这个答案,这正是正确的答案。为清楚起见,转载,但原文链接如下。
using System;
using System.Linq;
using System.Linq.Expressions;
public static class Extensions
{
public static IQueryable<T> WhereLike<T>(this IQueryable<T> source, string propertyName, string pattern)
{
if (null == source) throw new ArgumentNullException("source");
if (string.IsNullOrEmpty(propertyName)) throw new ArgumentNullException("propertyName");
var a = Expression.Parameter(typeof(T), "a");
var prop = Expression.Property(a, propertyName);
var body = Expression.Call(typeof(SqlMethods), "Like", null, prop, Expression.Constant(pattern));
var fn = Expression.Lambda<Func<T, bool>>(body, a);
return source.Where(fn);
}
}
...
.WhereLike("Description", "%a%b%c%"));
该解决方案使用表达式树,但所有高级LinqToSql操作都需要熟悉表达式树。
发布于 2010-07-28 11:52:15
与SqlMethods.Like实际做的事情相比,你想做的事情似乎没有什么意义。当您传入一个类的属性时,您实际上是在告诉它将其转换为SQL查询中的等价字段。例如:
var result = from names in db.Names
where SqlMethods.Like(names.FullName, '%Smith%')
select names;
会转化成类似这样的东西:
SELECT *
FROM Names
WHERE Fullname LIKE '%Smith%'
(在实践中,使用参数和sp_executeSQL会有所不同,但实际上它就是这样做的)。
如果你想传入一个属性的名称,这在SQL中意味着什么,从概念上讲没有任何意义,例如
SELECT *
FROM Names
WHERE --what would go here-- LIKE '%Smith%'
因此,您将无法创建创建无意义SQL的Linq to SQL方法。
你真正想做的是什么,很有可能你的做法完全错了。
编辑:从你的评论中我想我知道你想要做什么,在本质上你希望能够指定你在运行时与之进行相似比较的列。你不能完全做到这一点。您可以使用使用动态SQL并接受列的字符串参数的存储过程。然后,您可以将其作为数据上下文类上的方法公开。
https://stackoverflow.com/questions/3352381
复制相似问题