о предикате Func <TElement, bool> - PullRequest
2 голосов
/ 06 марта 2011
//my question is here
public static Query Where<TElement>(this Query query, Func<TElement, bool> predicate) 
{
     query.sql +=" FROM Table WHERE "+ predicate+";"; 
     return query; 
} 

//Query class 
public class Query 
{
     public Query(){}
     public Query(string sql){this.sql = sql;} 
     public string sql { set; get; } 
}

//User class 
public class User 
{ 
     public int ID { get; set; } 
     public string Name { get; set; } 
} 

//example: 
User user = new User() { ID=1,Name="test"}; 
Query query = new Query(); 
query = query.Where<User>(u=>u.ID==user.ID); 
Console.WriteLine(query.sql);

После запуска получается:

FROM Table WHERE System.Func'2[DAL.User,System.Boolean]';

Но мне нужно:

FROM Table WHERE ID=1;

Может кто-нибудь мне помочь?

Ответы [ 2 ]

3 голосов
/ 06 марта 2011

Если вы хотите узнать, как Linq to Sql работает над созданием SQL-запроса, ваш первый шаг будет состоять в изучении деревьев выражений .

Следующим шагом будет получениенекоторое знакомство с ExpressionVisitor , который поможет понять, как вы можете посетить каждую часть в дереве выражений.

Оттуда прочитайте серию блогов "LINQ: Создание серии провайдеров IQueryableMsgstr " о том, как разобрать дерево выражений в sql.

Пост "Где и повторно используемый посетитель дерева выражений" поможет разобрать ваш предикат.

Теперь, поскольку вы не будете работать с IQueryable<T>.Where(), нопросто Expression<Func<T, bool>> не все в этих постах будет относиться полностью, но должно послужить хорошим началом для того, чтобы разобрать выражение предиката в действительное предложение sql where.

Надеюсь, это поможет вам начать!

1 голос
/ 06 марта 2011

Похоже, что вы пытаетесь сделать свой класс запросов LINQ доступным здесь. Когда вы участвуете в предложении LINQ Where, полученный предикат является функциональным объектом, а не строкой. Идея состоит в том, что вы применяете функцию предиката к каждому перечисляемому элементу и возвращаете только те, для которых функция возвращает "true".

LINQ-to-SQL смотрит на код внутри предиката, подобного этому, который, как предполагается, является выражением (например, лямбда-выражением), которое он может анализировать и преобразовывать в выражение SQL. Помните, что лямбда C # может быть сгенерирована компилятором либо в делегат, либо в дерево выражений (см. этот раздел MSDN ), в зависимости от типа, ожидаемого в выражении, в котором оно находится. Поэтому LINQ-to-SQL другими словами, много работы, чтобы превратить этот предикат во что-то, что может работать с ядром базы данных.

Если вы действительно используете LINQ, вам, вероятно, придется просто получить все записи в вашем запросе и затем отфильтровать их, используя предикат, если только это не представляет проблему масштабирования (зависит от того, насколько серьезно ваше приложение). Кроме того, вам нужно написать правильную функцию Where, которая возвращает объект IEnumerable и использует yield-return. См. эту страницу руководства (вам придется немного прокрутить вниз) или прочитайте главы LINQ в превосходном C # в книге «В двух словах».

С другой стороны, если вы на самом деле не заботитесь о LINQ и этот код просто совпадает с LINQ-y, просто измените тип аргумента на строку и заключите в кавычки выражение, которое вы хотите использовать.

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