РЕДАКТИРОВАНИЕ:
Я пытаюсь создать запрос, используя деревья выражений, чтобы я мог получить простой результат, но я не смог его выяснить.
IУ меня есть некоторые объекты от EF.Entity PointOfSale, который имеет некоторые атрибуты, такие как: Location (который является дочерним для Region) TypeOfClient ImportanceOfPOS QuantityOfSales.
Затем у меня есть класс Filter, у которого есть список Regions, список TypesOfClients, Dist ofImportanceOfPOS, а также минимальное и максимальное значение количества продаж.
Классы определены ниже:
Контекст сущностей = новые сущности ();
class PointOfSale
{
int p_id;
Location l;
QuantityOfSales q;
TypeOfCliente t;
ImportanceOfClient i;
int l_id_fk;
int t_id_fk;
int i_id_fk;
}
class Location
{
int id;
int region_id_fk;
}
class Region
{
int id;
string value;
}
class ValuesForQuantity
{
int p_id; // ---> Equal to the POS_id
int? min_value;
int? max_value;
}
class QuantityOfSales
{
int id;
int value;
}
class TypeOfCliente
{
int id;
string value;
}
class ImportanceOfClient;
{
int id;
string value;
}
class Filter
{
List<Region> rs;
ValuesForQuantity v;
List<ImportanceOfClient> is;
List<TypeOfClient> ts;
}
Сохранитьпомните, что все поля являются необязательными: у меня могут быть или не быть регионы, у меня может быть или не быть TypeOfClient.Кроме того, в ValueForQuantities у меня может быть выбрано только одно из полей (только максимальное или минимальное).
Я пытаюсь создать динамическую версию этого:
var query =
from p in context.PointsOfSale
where p.i exists in filter.is &&
p.t exists in filter.ts &&
p.l in (from l1 in context.Locations where l1 in filter.rs select r) &&
p.t in (from q in context.Quantities where q.value < filter.v.max_value && q.value > filter.v.max_value)
select p;
, которое будетсгенерируйте код, подобный следующему:
(p.i.id == filter.i[0] OR p.i.id == filter.i[1] OR p.i.id == filter.i[2])
AND
(p.t.id == filter.t[0] OR p.t.id == filter.t[1])
AND
p.l in (select id from Region r where (r.id == filter.r[0] OR r.id == filter.r[1])
AND
p.q.value < filter.v.max
AND
p.q.value > filter.v.min
Мое дерево выражений до сих пор выглядит так:
IQueryable<Points_of_sale> queryableDataPOS = context.Points_of_sale.AsQueryable<Points_of_sale>();
ParameterExpression pePOS = Expression.Parameter(typeof(Points_of_sale), "point_of_sale");
ParameterExpression peLocation = Expression.Parameter(typeof(Location), "location");
List<Expression> expressions = new List<Expression>();
if (showRegion)
{
List<Location> ls = getAllLocations(regionList);
List<Expression> choiceExpressions = new List<Expression>();
foreach (Location l in ls)
{
Expression left = Expression.Property(pePOS, typeof(Points_of_sale).GetProperty("location_id_fk"));
left = Expression.Convert(left, t.location_id.GetType());
Expression right = Expression.Constant(t.territory_id);
Expression expression = Expression.Equal(left, right);
choiceExpressions.Add(expression);
}
if (choiceExpressions.Count > 0)
{
Expression totalChoiceExpression = choiceExpressions[0];
for (int i = 1; i < choiceExpressions.Count; i++)
{
totalChoiceExpression = Expression.Or(totalChoiceExpression, choiceExpressions[i]);
}
expressions.Add(totalChoiceExpression);
}
}
if (showTypeOfClient)
{
List<Expression> choiceExpressions = new List<Expression>();
foreach (TypeOfClient choice in clients)
{
Expression left = Expression.Property(pePOS, typeof(Points_of_sale).GetProperty("type_of_client_id_fk"));
left = Expression.Convert(left, choice.type_of_client.GetType());
Expression right = Expression.Constant(choice.type_of_client_id);
Expression expression = Expression.Equal(left, right);
choiceExpressions.Add(expression);
}
if (choiceExpressions.Count > 0)
{
Expression totalChoiceExpression = choiceExpressions[0];
for (int i = 1; i < choiceExpressions.Count; i++)
{
totalChoiceExpression = Expression.Or(totalChoiceExpression, choiceExpressions[i]);
}
expressions.Add(totalChoiceExpression);
}
}
if (showImportanceOfClient)
{
List<Expression> choiceExpressions = new List<Expression>();
foreach (ImportanceOfClient choice in importanceOfClients)
{
Expression left = Expression.Property(pePOS, typeof(Points_of_sale).GetProperty("importance_of_client_id_fk"));
left = Expression.Convert(left, choice.importance_of_client_id.GetType());
Expression right = Expression.Constant(choice.importance_of_client_id);
Expression expression = Expression.Equal(left, right);
choiceExpressions.Add(expression);
}
if (choiceExpressions.Count > 0)
{
Expression totalChoiceExpression = choiceExpressions[0];
for (int i = 1; i < choiceExpressions.Count; i++)
{
totalChoiceExpression = Expression.Or(totalChoiceExpression, choiceExpressions[i]);
}
expressions.Add(totalChoiceExpression);
}
}
if (showQuantityOfSales)
{
// I have no idea how to build this one
}
Expression totalQuery = expressions[0];
// Make the && between all expressions
for (int i = 1; i < expressions.Count; i++)
{
totalQuery = Expression.And(totalQuery, expressions[i]);
}
MethodCallExpression whereCallExpression = Expression.Call(
typeof(Queryable),
"Where",
new Type[] { queryableDataPOS.ElementType },
queryableDataPOS.Expression,
Expression.Lambda<Func<Points_of_sale, bool>>(totalQuery, new ParameterExpression[] { pePOS }));
IQueryable<Points_of_sale> results = queryableDataPOS.Provider.CreateQuery<Points_of_sale>(whereCallExpression);
Итак, 2 вопроса:
1 - Как мне построитьчасть региона без метода, который возвращает все местоположения.2 - Как я могу создать ветвь дерева выражений для количества?