Как написать этот Linq SQL как динамический запрос (используя строки)? - PullRequest
6 голосов
/ 28 марта 2010

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

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

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

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

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

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

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 - фантастика, но все еще в поисках ответа. В конце концов, совершенно случайные исследования, подобные этому, будут преобладать, я думаю. LOL.

Edit:

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

Ответы [ 2 ]

4 голосов
/ 04 апреля 2010

Я не уверен, как это сделать, используя синтаксис запроса (как выше), но используя синтаксис метода, мы можем использовать выражение

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();
        }
    }
}
1 голос
/ 01 апреля 2010

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

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

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

...