El sindicato EF 5 no funciona como se esperaba
-
11-12-2019 - |
Pregunta
Tengo una consulta de linq que involucra las siguientes 3 entidades:
public class LandPoint
{
...
public OlsonTimeZone TimeZone { get; set; }
}
public class OlsonTimeZone : TimeZone
{
...
public virtual ICollection<WindowsTimeZone> Windows { get; set; }
}
public class WindowsTimeZone : TimeZone
{
...
public virtual ICollection<OlsonTimeZone> Olson { get; set; }
}
Entonces, un LandPoint tiene un OlsonTimeZone que tiene cero o más WindowsTimeZones.
Lo que estoy tratando de hacer es obtener el nombre de WindowsTimeZone (con el prefijo 'Windows:') si OlsonTimeZone tiene WindowsTimeZones o el nombre de OlsonTimeZone (con el prefijo 'Olson:') como recurso alternativo junto con información sobre el punto en sí.
Lo que he escrito es:
return db.LandPoints.Where(x => x.GeoNameID == ID).Take(1).Select(x => new LandPoint
{
TimeZone = x.TimeZone
.Windows.Select(t => "Windows:" + x.Name)
.Union(new[] { "Olson:" + x.TimeZone.Name })
.FirstOrDefault()
}).First();
Que en teoría debería hacer lo que quiero.Excepto que para un punto determinado con el que lo probé (que sé que tiene un WindowsTimeZone asociado) devolvió OlsonTimeZone en lugar de WindowsTimeZone.Si para el mismo ID escribo lo siguiente:
return db.LandPoints.Where(x => x.GeoNameID == ID).Take(1).Select(x => new LandPoint
{
TimeZone = x.TimeZone
.Windows.Select(t => "Windows:" + x.Name)
.FirstOrDefault()
}).First();
Obtengo WindowsTimeZone.
Estoy seguro de que podría reescribirlo usando una declaración CASE, pero sentí que era más elegante.Dado que su comportamiento es algo contrario a la intuición y comprender por qué hace lo que hace me ayudaría a tener una mejor idea de cómo se traducen las consultas de LINQ a SQL, decidí publicar una pregunta aquí.
Entonces, ¿por qué hace lo que hace?¿Hay alguna adición al código anterior que lo haría funcionar (manteniendo la declaración UNION)?
Gracias de antemano John
Solución
Es porque la unión no garantiza el pedido.No puedes poner expectativas especiales basadas en el orden de los artículos sin ordenarlos.Pero tu código debería activarse NotSupportedException
porque esto no está permitido: db.LandPoints.Select(x => new LandPoint ...
Si usted tiene LandPoint
entidad asignada por el marco de la entidad no se puede proyectar a este tipo en Linq-to-entities.