2012-04-26 37 views
6

Utilizo EntityFramework con POCO.
Supongamos que tengo POCOs define como esto (simplificado):consulta LINQ con una cláusula WHERE con varias condiciones

class Class1 
{ 
    public int ID; 
    public int SomeNumber; 
} 

class Class2 
{ 
    public int ID; 
    public int SomeNumber; 
} 

class Class3 
{ 
    public int ID; 
    public int SomeNumber; 
} 

class SomeClass 
{ 
    public int ID; 
    public int? Class1ID; 
    public Class1 Class1; 
    public int? Class2ID; 
    public Class2 Class2; 
    public int? Class3ID; 
    public Class3 Class3; 
} 

que queremos obtener todas las SomeClass registros de la base de datos, que pertenecen a una cualquiera de Class1, Class2 o Class3ClassX.SomeNumber, donde es igual a un número.

escribí la consulta LINQ que se parece a esto:

Database DB = new Database(); // object context 
var result = DB.SomeClass.ToList(); 

int SomeNumber = 1; // some number 
List<SomeClass> retValue = result 
    .Where(x => 
     { 
      int Number = 0; 
      if (x.Class1 != null) 
       Number = x.Class1.SomeNumber; 
      else if (x.Class2 != null) 
       Number = x.Class2.SomeNumber; 
      else if (x.Class3 != null) 
       Number = x.Class3.SomeNumber; 
      return Number == SomeNumber; 
     }) 
    .ToList(); 

... retValue sin embargo no contiene ningún registro.

La solución

Al parecer, tenían que especificar .Include declaraciones debido a la carga diferida fue desactivada y x.Class1, x.Class2 y x.Class3 siempre ha tenido el valor null. Me siento avergonzado porque no dije explícitamente que la carga lenta estaba desactivada; el problema habría sido obvio entonces.

Sin embargo, gracias al post de Ladislav, he mejorado mi código de este modo:

Database DB = new Database(); // object context 

int SomeNumber = 1; // some number 
List<SomeClass> retValue = DB.SomeClass 
    .Include("Class1") 
    .Include("Class2") 
    .Include("Class3") 
    .Where(x => 
     SomeNumber == x.Class1.SomeNumber || 
     SomeNumber == x.Class2.SomeNumber || 
     SomeNumber == x.Class3.SomeNumber) 
    .ToList(); 

no sabía LINQ a entidades deben realizar coalescente nula automática.

Respuesta

3

en mi humilde opinión debería estar de acuerdo con esto:

Database DB = new Database(); 
var result = DB.SomeClass.Where(x => 
          Number == x.Class1.SomeNumber || 
          Number == x.Class2.SomeNumber || 
          Number == x.Class3.SomeNumber) 
         .ToList(); 

Sus cargas de consulta todos los datos y después de que evaluar la condición en .NET = debe probar valor nulo antes de acceder SomeNumber pero eso no es necesario si usted evalúa SomeNumber en SQL a través de Linq-to-entities. Linq-to-entities debe realizar coalescencia nula automática.

+0

En realidad, la solución se (normalmente encontrar yo mismo poco después de que pido) que, debido a la carga diferida desactivado , Tuve que hacer 'var result = DB.SomeClass.Include (" Class1 "). Include (" Class2 "). Include (" Class3 ")' antes de ejecutar la cláusula 'Where'. Sin embargo, estoy marcando esto como aceptado porque me enseñaste a mejorar mi código (usa 'Where' en LINQ-To-Entities directamente) –

2

Según su lógica, si x.Class1 no es nulo, pero x.Class1.SomeNumber es 3, no revisará todas las demás cláusulas.

Si desea comprobar, si sólo algunas ClassN.SomeNumber == SomeNumber, entonces usted debe hacerlo de esta manera:

int SomeNumber = 1; // some number 
List<SomeClass> retValue = result 
    .Where(x => 
     { 
      if (x.Class1 != null && x.Class1.SomeNumber == SomeNumber) 
       return true; 
      else if (x.Class2 != null && x.Class2.SomeNumber == SomeNumber) 
       return true; 
      else if (x.Class3 != null && x.Class3.SomeNumber == SomeNumber) 
       return true; 
      return false; 
     }) 
    .ToList(); 
+0

¿No es este código el mismo que el que yo usé, excepto que mi código tiene 1 más ¿línea? –

+0

No, ya que vuelve inmediatamente si los números son iguales. En su código es posible, que hay un número correcto, pero se sobrescribe por otra cláusula if. – LueTm

+0

No se puede anular porque hay cláusulas 'else', y devolvería 0 si ninguna de las condiciones coincide. –

Cuestiones relacionadas