Как написать этот Linq SQL как динамический запрос (используя строки)?

При необходимости перейдите к «конкретному вопросу». Немного фона:

Сценарий: у меня есть набор продуктов с фильтром "детализации" (объект запроса), заполненным DDL. Каждый прогрессивный выбор DDL будет дополнительно ограничивать список продуктов, а также то, какие параметры остаются для DDL. Например, выбор молотка из инструментов ограничивает размеры продукта, показывая только размеры молотка.

Текущая настройка: я создал объект запроса, отправил его в репозиторий и передал каждый параметр в "табличную функцию" SQL, где нулевые значения означают "получить все продукты".

Я считаю это хорошей попыткой, но далеко не приемлемой для DDD. Я хочу избежать какого-либо «программирования» на SQL, надеюсь, все сделаю с репозиторием. Комментарии по этой теме приветствуются.

Конкретный вопрос:

Как мне переписать этот запрос как Динамический запрос? Ссылка на что-то вроде 101 Linq Examples была бы прекрасной, но с область динамического запроса. Я действительно хочу передать этому методу поле в кавычках "", для которого я хочу список опций и сколько продуктов имеют эту опцию.

from   p in db.Products
group  p by p.ProductSize into g
select new Category { 
       PropertyType = g.Key,
       Count = g.Count() }

Каждый вариант DDL будет иметь «Выбор (21)», где (21) — это количество продуктов, которые имеют этот атрибут. После выбора параметра все остальные оставшиеся DDL будут обновлены с учетом оставшихся параметров и счетчиков.

Изменить: Дополнительные примечания:

.OrderBy("it.City") // "it" refers to the entire record
.GroupBy("City", "new(City)") // This produces a unique list of City
.Select("it.Count()") //This gives a list of counts... getting closer
.Select("key") // Selects a list of unique City
.Select("new (key, count() as string)") // +1 to me LOL.  key is a row of group
.GroupBy("new (City, Manufacturer)", "City") // New = list of fields to group by
.GroupBy("City", "new (Manufacturer, Size)") // Second parameter is a projection

Product
.Where("ProductType == @0", "Maps")
.GroupBy("new(City)", "new ( null as string)")// Projection not available later?
.Select("new (key.City, it.count() as string)")// GroupBy new makes key an object

Product
.Where("ProductType == @0", "Maps")
.GroupBy("new(City)", "new ( null as string)")// Projection not available later?
.Select("new (key.City, it as object)")// the it object is the result of GroupBy

var a = Product
        .Where("ProductType == @0", "Maps")
        .GroupBy("@0", "it", "City") // This fails to group Product at all
        .Select("new ( Key, it as Product )"); // "it" is property cast though

На данный момент я узнал, что LinqPad — это фантастика, но я все еще ищу ответ. В конце концов, я думаю, возобладают совершенно случайные исследования, подобные этому. РЖУ НЕ МОГУ.

Изменить:

У Джона Скита была фантастическая идея: использовать то, что мне нужно, как IGrouping<string, Product>. Спасибо Джону Скит! После приведения объекта вы можете перечислить наборы и передать результаты в отдельный список.


person Community    schedule 28.03.2010    source источник
comment
Вам нужен целый динамический запрос? Разве ваши критерии фильтрации (предложение Where) не являются единственным динамическим аспектом?   -  person Gabe    schedule 29.03.2010
comment
Я считаю, что мне нужен полный DQ. Без дублирования этого кода для каждого поля, которое они хотят отфильтровать, мне нужно было бы указать поле GroupBy в виде строки.   -  person Zachary Scott    schedule 29.03.2010
comment
Приведение к IGrouping‹string, Product› возможно только при возврате 'it'. Когда вы используете .Select(new (Key, it as Product, count() as count)) как использовать это ????   -  person Stef Heyenrath    schedule 01.11.2012


Ответы (2)


Я не уверен, как это сделать, используя синтаксис запроса (как указано выше), но используя синтаксис метода, мы можем использовать выражение‹Func‹, как показано ниже. Этот пример работает с базой данных AdventureWorks SQL Server (таблица «Продукты») и позволяет указать, какой столбец следует сгруппировать, используя строку (в этом примере я выбрал «Размер»).

using System;
using System.Linq;
using System.Linq.Expressions;

namespace LinqResearch
{
    public class Program
    {
        [STAThread]
        static void Main()
        {
            string columnToGroupBy = "Size";

            // generate the dynamic Expression<Func<Product, string>>
            ParameterExpression p = Expression.Parameter(typeof(Product), "p");

            var selector = Expression.Lambda<Func<Product, string>>(
                Expression.Property(p, columnToGroupBy),
                p
            );

            using (LinqDataContext dataContext = new LinqDataContext())
            {
                /* using "selector" caluclated above which is automatically 
                compiled when the query runs */
                var results = dataContext
                    .Products
                    .GroupBy(selector)
                    .Select((group) => new { 
                        Key = group.Key, 
                        Count = group.Count()
                    });

                foreach(var result in results)
                    Console.WriteLine("{0}: {1}", result.Key, result.Count);
            }

            Console.ReadKey();
        }
    }
}
person Community    schedule 03.04.2010

Если вы посмотрите на C# Bits , автор обсуждает, как создавать каскадные фильтры с использованием динамических данных. Не похоже, что вы используете динамические данные, но у него есть хороший построитель выражений, который может быть вам полезен. См. BuildQueryBody, а затем следующий раздел методов расширения в Iqueryable.

Поскольку вы не используете динамические данные, вам нужно будет иметь дело с отсутствием доступа к объекту «MetaForeignKeyColumn», но я подозреваю, что его подход может помочь вам с вашим вопросом.

Надеюсь, это поможет.

person Community    schedule 01.04.2010