扩展SqlMethods.Like以支持属性名称

时间:2010-07-28 11:32:25

标签: c# linq-to-sql

我正在尝试扩展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?

2 个答案:

答案 0 :(得分:1)

我从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操作都需要熟悉它。

来自:http://forums.asp.net/p/1488418/3503874.aspx

答案 1 :(得分:0)

在SqlMethods.Like实际执行的内容中,您想要做什么似乎没有意义。传入类的属性时,实际上是在告诉它将其转换为SQL查询中的equivelent字段。 e.g。

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方法。

你实际上想要做什么,你可能会以错误的方式解决这个问题。

编辑:嗯,从你的评论我想我明白你想要做什么,在本质上,你希望能够指定你在运行时进行LIKE比较的列。你不能完全这样做。您可以使用使用动态SQL的存储过程并为该列获取字符串参数。然后,您可以将其作为数据上下文类的方法公开。

相关问题