Estoy tratando de escribir Linq con múltiples cláusulas where y la cláusula where contiene además condiciones if en línea.

List<MeetingVM> students = (
from s in db.Meetings 
where MeetingIsActive == null || s.IsActive == MeetingIsActive 
where MeetingStat == null || MeetingStat == 5 ? (DateTime.UtcNow >= s.MeetingStartTime && DateTime.UtcNow <= s.MeetingStopTime) : s.Status== MeetingStat
where StartDate == null || (s.MeetingStartTime >= StartDate && s.MeetingStartTime <= EndDate) 
where s.Status!=4 
orderby s.MeetingStartTime ascending 
select new MeetingVM
{
    MeetingStartTime = s.MeetingStartTime,
    MeetingStopTime = s.MeetingStopTime,
    Alias = s.Alias,
    MeetingSubject = s.MeetingSubject,
    UserId = s.UserId,
    Status=s.Status

}).ToList();

Esto si la condición se ejecuta (DateTime.UtcNow> = s.MeetingStartTime && DateTime.UtcNow <= s.MeetingStopTime) incluso si MeetingStat == null.

where MeetingStat == null || MeetingStat==5 ? (DateTime.UtcNow >= s.MeetingStartTime && DateTime.UtcNow <= s.MeetingStopTime) : s.Status== MeetingStat

Si elimino esto ...

MeetingStat==5 ? (DateTime.UtcNow >= s.MeetingStartTime && DateTime.UtcNow <= s.MeetingStopTime) :

Funciona. Pero quería escribir esto para comprobar

if (MeetingStat==5)
  (DateTime.UtcNow >= s.MeetingStartTime && DateTime.UtcNow <= s.MeetingStopTime) 
else 
  s.Status== MeetingStat.

¿Qué mal estoy haciendo?

0
RackM 14 dic. 2016 a las 09:23

2 respuestas

La mejor respuesta

Primero, formateemos el código de una manera que no sea estúpidamente difícil de leer:

List<MeetingVM> students = (
    from s in db.Meetings 
    where MeetingIsActive == null || s.IsActive == MeetingIsActive 
    where MeetingStat == null || MeetingStat == 5 ? (DateTime.UtcNow >= s.MeetingStartTime && DateTime.UtcNow <= s.MeetingStopTime) : s.Status== MeetingStat
    where StartDate == null || (s.MeetingStartTime >= StartDate && s.MeetingStartTime <= EndDate) 
    where s.Status!=4 
    orderby s.MeetingStartTime ascending 
    select new MeetingVM
    {
        MeetingStartTime = s.MeetingStartTime,
        MeetingStopTime = s.MeetingStopTime,
        Alias = s.Alias,
        MeetingSubject = s.MeetingSubject,
        UserId = s.UserId,
        Status=s.Status

    }).ToList();

Eso está un poco mejor.

Ahora, no estoy 100% seguro de esto, así que alguien que sepa más puede sentirse libre de corregirme, pero de acuerdo con Precedencia del operador C #, el operador OR (" || ") tiene una precedencia mayor que el operador condicional ("?: "), por lo que línea:

where MeetingStat == null || MeetingStat == 5 ? ...

Esencialmente está siendo evaluado así:

where (MeetingStat == null || MeetingStat == 5) ? ...

Si MeetingStat es igual a verdadero, esto haría que la expresión evaluara la primera rama de la operación ternaria. A juzgar por la descripción de su pregunta, esto no es lo que desea, por lo que le recomiendo que rodee la operación ternaria entre paréntesis para dejar clara su intención:

where MeetingStat == null || (MeetingStat == 5 ? ... )
0
Abion47 14 dic. 2016 a las 06:46

Creo que el problema es con DateTime.UtcNow Es mejor almacenar su valor en una variable y luego usar el mismo en LINQ de esta manera:

DateTime UtcTime = DateTime.UtcNow;
// and change the condition like this;
.Where MeetingStat != null && MeetingStat==5 ? (UtcTime >= s.MeetingStartTime && UtcTime <= s.MeetingStopTime) : s.Status== MeetingStat

Está sucediendo así porque sus predicados dentro de la cláusula Where no se estaban traduciendo a SQL, si está usando esto significa que su código funcionará como se esperaba ya que UtcTime ahora es convertible

0
sujith karivelil 14 dic. 2016 a las 06:54