расширение SqlMethods.Like для поддержки имени свойства - PullRequest
0 голосов
/ 28 июля 2010

Я пытаюсь расширить метод 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 ]

1 голос
/ 29 июля 2010

Я нашел этот ответ от 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

0 голосов
/ 28 июля 2010

То, что вы хотите сделать, похоже, не имеет смысла в контексте того, что на самом деле делает 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, но по сути это то, что он будет делать).1008 * Если вы хотите передать имя свойства, что это значит с точки зрения SQL, концептуально это не имеет смысла, например:

SELECT * 
FROM Names
WHERE --what would go here-- LIKE '%Smith%'

Таким образом, вы не сможете создать LinqК методу SQL, который создает бессмысленный SQL.

Что вы на самом деле пытаетесь сделать, есть вероятность, что вы делаете это совершенно неправильно.

Редактировать: хм из вашего комментария, я думаюя понимаю, что вы хотите сделать, в сущности, вы хотите иметь возможность указать столбец, с которым вы сравниваете LIKE во время выполнения.Вы не можете сделать это точно.Вы можете использовать хранимую процедуру, которая использует динамический SQL и принимает строковый параметр для столбца.Затем вы можете представить это как метод в своем классе контекста данных.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...