Re[6]: Увы...
От: Idsa Россия  
Дата: 21.07.08 06:01
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Зато Linq2Sql может

К сожалению, он много чего другого не может
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[5]: Увы...
От: Ziaw Россия  
Дата: 21.07.08 06:33
Оценка:
Здравствуйте, J_K, Вы писали:

J_K>Попытка использовать Contains успехом не увенчалась. Возник эксепшн:


J_K>LINQ to Entities does not recognize the method 'Boolean Contains(Int32)' method, and this method cannot be translated into a store expression.


Значит надо самостоятельно создать нужный expression.
Например в виде цепочки c.CategoryId = 1 || c.CategoryId = 2 || c.CategoryId = n.
Ее LINQ to Entities понять просто обязан.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;

namespace LinqDynamicExpression
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var dc = new TestDataContext())
            {
                dc.Customers.DeleteAllOnSubmit(dc.Customers);
                dc.Customers.InsertAllOnSubmit(new[]
                {
                    new Customer {CategoryId = 1},
                    new Customer {CategoryId = 3},
                    new Customer {CategoryId = 10},
                    new Customer {CategoryId = 11},
                });
                dc.SubmitChanges();

                dc.Log = Console.Out;

                var categories = new[] {1, 2, 3};

                var result = dc.Customers
                    .Where(categories.BuildContainsAnalogue<Customer, int>(c => c.CategoryId))
                    .ToList();

                Debug.Assert(result.Count == 2);
                Debug.Assert(result.All(c => categories.Contains(c.CategoryId)));
            }
        }
    }

    public static class ContainsAnalogue
    {
        public static Expression<Func<T, bool>> BuildContainsAnalogue<T, C>(
            this IEnumerable<C> collection,
            Expression<Func<T, C>> propertyLambda)
        {
            var propertyGetter = propertyLambda.Body;

            var firstElem = Expression.Constant(collection.First(), typeof(C));
            var orChain = Expression.Equal(propertyGetter, firstElem);

            foreach (var item in collection.Skip(1))
            {
                var curElem = Expression.Constant(item, typeof(C));
                orChain = Expression.Or(orChain, Expression.Equal(propertyGetter, curElem));
            }

            return Expression.Lambda<Func<T, bool>>(orChain, propertyLambda.Parameters);
        }
    }
}


Запрос в данном случае получается такой.

SELECT [t0].[Id], [t0].[CategoryId]
FROM [dbo].[Customer] AS [t0]
WHERE ([t0].[CategoryId] = @p0) OR ([t0].[CategoryId] = @p1) OR ([t0].[CategoryId] = @p2)
-- @p0: Input Int (Size = 0; Prec = 0; Scale = 0) [1]
-- @p1: Input Int (Size = 0; Prec = 0; Scale = 0) [2]
-- @p2: Input Int (Size = 0; Prec = 0; Scale = 0) [3]
... << RSDN@Home 1.2.0 alpha 4 rev. 0>>
Re[7]: Увы...
От: Lloyd Россия  
Дата: 21.07.08 07:42
Оценка:
Здравствуйте, Idsa, Вы писали:

L>>Зато Linq2Sql может

I>К сожалению, он много чего другого не может

Во многих случаях оно и не надо
... << RSDN@Home 1.2.0 alpha rev. 786>>
Re[8]: Увы...
От: Idsa Россия  
Дата: 21.07.08 07:58
Оценка:
Здравствуйте, Lloyd, Вы писали:

L>Во многих случаях оно и не надо

Хз, хз. Сейчас занимаюсь переводом DAL'а с Linq to Sql на Entity Framework... испытываю исключительно положительные эмоции
Как вспомню ту жесть, когда невозможно было обновить модель с измененными значениями, а проект развивается и развивается...
Да и вообще, много полезных плюшек появилось.
... << RSDN@Home 1.2.0 alpha 4 rev. 1096>>
Re[3]: LINQ - Динамическое построение запроса
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.08.08 07:13
Оценка: -1
Здравствуйте, J_K, Вы писали:
J_K>Эта конструкция и была мне нужна, но! Разве select не должен идти последним?
Да. Он и так идет последним.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.