#c# #entity-framework #linq #datetime #lambda
#c# #entity-framework #linq #datetime #лямбда
Вопрос:
Я пытаюсь создать предложение WHERE во время выполнения. Я создал запрос с начальным предложением WHERE:
var origSQL = (from ....
join ...
where ...
select new { ... } );
и будет добавлено следующее WHERE в origSQL:
var endDate = (from table1 in db.Table1
join aliasTable1 in db.Table1 on table1.id equals aliasTable1.id
where aliasTable1.anotherId == anInputStr
amp;amp; (table1.field1 == aliasTable1.field1)
select DbFunctions.TruncateTime(aliasTable1.endDate)).Max();
...
Конечная дата будет нуждаться в дальнейшем уточнении перед присоединением к исходному WHERE, например:
if (!string.IsNullOrEmpty(anotherInputStr) amp;amp; (anotherInputStr == "FOO"))
endDate = endDate.Where ( a=> aliasTable1.GRADE == "F" );
При этом я получаю сообщение об ошибке:
DateTime does not contain a definition for Where accepting a first argument of type DateTime
Поэтому я удалил часть выбора из начальной конечной даты, полагая, что смогу добавить ее позже:
var endDateCriteria = from table1 in db.Table1
join aliasTable1 in db.Table1 on table1.id equals aliasTable1.id
where aliasTable1.anotherId == anInputStr
amp;amp; (table1.field1 == aliasTable1.field1)
if (!string.IsNullOrEmpty(anotherInputStr) amp;amp; (anotherInputStr == "FOO"))
endDateCriteria = endDateCriteria .Where ( a=> aliasTable1.GRADE == "F" );
Но
.Where
все еще вызывает проблему. Мне нужно добавить кучу этих проверок, которые будут добавлены к this WHERE, чтобы затем быть добавленными к исходному запросу, и я не могу найти правильный синтаксис.
Добавлено, что это изначально самосоединение. Исходный динамический SQL выглядит следующим образом
origSQL := ' AND table1.endDate = (
SELECT MAX(endDate)
FROM table1 aliasTable1
WHERE aliasTable1.ID = table1.ID)
И я пытаюсь добавить дополнительные предложения WHERE к этому, которые затем полностью будут добавлены к основному запросу. Я не знаю синтаксиса для этого.
Комментарии:
1. Можете ли вы показать, какой тип данных
endDateCriteria
?2. Ваш
.Max()
гарантирует, что вы не возвращаете перечислимые или запрашиваемые, а скорее одну дату, на которую вы не можете выполнятьWhere()
или аналогичные функции linq. Возможные решения: выберите несколько значений вместо только даты или вместо.Max();
попыткиToList();
выполнить проверку.3. Какая сущность обладает этим
GRADE
свойством? В вашем втором запросе вы не опубликовали то, что выбираете (вы всегда должны что-то выбирать).4. @Jacky: это тип DateTime, возвращаемый из предложения select .
5. @Andrew: это еще одно поле в (псевдонимной) самосоединяющейся таблице table1, но это условие, которое должно быть включено только в том случае, если выполняется <предикат> .
Ответ №1:
Каждый запрос должен иметь select , который будет определять, что будет содержать ваша переменная. Во втором примере у вас его нет, поэтому он не компилируется. Вы должны сделать что-то вроде этого:
var endDateCriteria = from table1 in db.Table1
join aliasTable1 in db.Table1 on table1.id equals aliasTable1.id
where aliasTable1.anotherId == anInputStr
amp;amp; (table1.field1 == aliasTable1.field1)
select new { table1, aliasTable1 };
if (!string.IsNullOrEmpty(anotherInputStr) amp;amp; (anotherInputStr == "FOO"))
endDateCriteria = endDateCriteria.Where(q => q.aliasTable1.GRADE == "F");
if (somethingElse)
endDateCriteria = endDateCriteria.Where(q => q.aliasTable1.field1 > value);
if (otherCondition)
endDateCriteria = endDateCriteria.Where(q => q.table1.field2 != value2);
DateTime result = endDateCriteria.Max(q => q.aliasTable1.endDate).Date;
Здесь я сохраняю endDateCriteria
обе таблицы в анонимном объекте, поэтому позже я могу продолжить использовать обе таблицы для своих условий, и в итоге я получаю максимальную дату. Я не вижу необходимости использовать TruncateTime
.
Ответ №2:
Отредактированный ответ с условием, упомянутым в комментарии оригинальным постером:
var endDates = (from table1 in db.Table1
join table2 in db.Table2 on table1.id equals table2.id
where table2.anotherId == anInputStr
amp;amp; (table1.field1 == table2.field1);
if(YOUR CONDITION)
{
endDates = endates.Where(e=> e.).Grade == "F")
}
var endate = from endates select DbFunctions.TruncateTime(table2.endDate)).Max();
Изначально вы работали с одним объектом (таблица максимальных значений 2.enddate) .Where
, который действует на коллекцию.
var endDate = (from table1 in db.Table1
join table2 in db.Table2 on table1.id equals table2.id
where table2.anotherId == anInputStr
amp;amp; (table1.field1 == table2.field1)
amp;amp; таблица (я не знаю, какая таблица).Оценка == «F»
select DbFunctions.TruncateTime(table2.endDate)).Max();
Комментарии:
1. Я исправил, чтобы проиллюстрировать, где должна быть получена оценка, если условие выполнено. Я должен добавить предложение условно и не нашел синтаксиса.
2. Это не сработает, вам нужно что-то выбрать, и
.Where
от этого будет зависеть следующее. Пожалуйста, проверьте свой синтаксис, в котором много ошибок.