Как использовать system. linq. dynamic для построения динамического предложения where
Эй, ребята, что случилось?
Сейчас мы работаем над проектом в моей компании (C # & ASP.Net) и на одной из страниц есть механизм, который извлекает некоторые данные из таблицы с помощью WCF.
Пока все так хорошо!
эти данные хранятся внутри класса DTO (назовем его Tikun94ActualPerformanceSummaryDto), и в конечном итоге я преобразую их в такой объект IEnumerable:
IEnumerable<Tikun94ActualPerformanceSummaryDTO> filtered = this.Tikun94Summaries as IEnumerable<Tikun94ActualPerformanceSummaryDTO>;
(Tikun94Summaries - это объект типа Tikun94ActualPerformanceSummaryDto).
Теперь эти данные просматриваются через таблицу на странице, и пользователь может отфильтровать таблицу, используя несколько вариантов, которые я ему даю.
Нажимая кнопку "Отправить", я хочу перебрать существующий "фильтр" (типа IEnumerable, который я создал ранее) и отфильтровать его по значениям, данным мне пользователем.
Для каждого значения, заданного пользователем, мне нужно установить предложение Where, которое фильтр "фильтрует" снова и снова. Теперь, поскольку я не хочу снова и снова запрашивать один и тот же IEnumerable "filtered" , я хочу построить Where динамически
и чем запустить его только один раз.
Давайте посмотрим немного кода:
IEnumerable<Tikun94ActualPerformanceSummaryDTO> filtered = this.Tikun94Summaries as IEnumerable<Tikun94ActualPerformanceSummaryDTO>; IQueryable<Tikun94ActualPerformanceSummaryDTO> queryableData = filtered.AsQueryable();
Здесь (выше), как вы можете видеть, я начинаю с преобразования объекта IEnumerable в объект IQueryable, чтобы сделать следующее:
string query = "filtered.Where(";
Теперь я начинаю проверять значения, заданные пользователем, и устанавливаю Where в соответствии с ними, используя switch Case (возьмем в качестве примера 2 случая):
#region OperatorLineId switch (cmbLine.SelectedValue) { case "0": query += += "u => u.OperatorLineId == u.OperatorLineId "; break; default: query += "u => u.OperatorLineId == Convert.ToInt32(cmbLine.SelectedValue) "; break; } #endregion #region ExclusivityLine switch (ddlExclusivityLine.SelectedValue) { case "0": query += "AND u => u.ExclusivityLine == u.ExclusivityLine "; break; default: query += "AND u => u.ExclusivityLine == ddlExclusivityLine.SelectedValue )"; break; } #endregion var externals = new Dictionary<string, object>(); externals.Add("filtered", queryableData);
И вот тут я получаю экзекуцию :-( :
var expression = System.Linq.Dynamic.DynamicExpression.Parse(typeof(IQueryable<Tikun94ActualPerformanceSummaryDTO>), query, new[] {externals});
Сообщение об исключении:
"Никакое свойство или поле" у " существует в тип 'Tikun94ActualPerformanceSummaryDto'"
У меня есть несколько догадок о том, что я делал неправильно. Может быть, я пытаюсь использовать лямбда-выражение там, где мне это не положено, и, возможно, я не получаю прямого доступа к элементам внутри DTO cuu. Мотыга могу ли я получить доступ к значениям внутри DTO? может быть, я не должен?
В конце концов, я хочу построить это предложение Where динамически (в некоторых случаях переключения я должен использовать оператор '>' или '<').
Я предполагаю, что у меня есть более чем одна ошибка при написании этого алгоритма, и я хотел бы знать, каков правильный синтаксис для написания этой операции.
Это класс Tikun94ActualPerformanceSummaryDto (там, конечно, есть еще много параметров, но здесь это просто пример):
using System; using WcfSerialization = global::System.Runtime.Serialization; namespace OpsReporting.DataContracts { [WcfSerialization::DataContract(Namespace = "urn:OperatorsReporting.ServiceContracts", Name = "Tikun94ActualPerformanceParamDTO")] public partial class Tikun94ActualPerformanceSummaryDTO { public int operatorLineId; public string exclusivityLine; [WcfSerialization::DataMember(Name = "OperatorLineId", IsRequired = true, Order = 6)] public int OperatorLineId { get { return operatorLineId; } set { operatorLineId = value; } } [WcfSerialization::DataMember(Name = "ExclusivityLine", IsRequired = true, Order = 8)] public string ExclusivityLine { get { return exclusivityLine; } set { exclusivityLine = value; } } }
Большое спасибо!
Что я уже пробовал:
Лоты: см. выше