Союз EF 5 не работает должным образом
-
11-12-2019 - |
Вопрос
У меня есть запрос linq, включающий следующие три объекта:
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; }
}
Таким образом, LandPoint имеет OlsonTimeZone, который имеет ноль или более WindowsTimeZone.
Я пытаюсь получить имя WindowsTimeZone (с префиксом «Windows:»), если OlsonTimeZone имеет какие-либо WindowsTimeZones, или имя OlsonTimeZone (с префиксом «Olson:») в качестве запасного варианта вместе с информацией о самой точке.
Я написал следующее:
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();
Который теоретически должен делать то, что я хочу.За исключением того, что для данной точки, с которой я его тестировал (с которой, как я знаю, связана WindowsTimeZone), он вернул OlsonTimeZone вместо WindowsTimeZone.Если для того же идентификатора я пишу следующее:
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();
Я получаю WindowsTimeZone.
Я уверен, что мог бы переписать его, используя оператор CASE, но мне показалось, что это более элегантно.Поскольку его поведение несколько противоречит интуитивному и понимание того, почему он делает то, что делает, поможет мне лучше понять, как запросы linq переводятся в sql, я решил задать вопрос здесь.
Так почему же он делает то, что делает?Есть ли какое-нибудь дополнение к приведенному выше коду, которое позволило бы ему работать (с сохранением оператора UNION)?
Заранее спасибо Джон
Решение
Это потому, что объединение не гарантирует упорядоченность.Вы не можете возлагать какие-либо особые ожидания в зависимости от порядка предметов, не заказывая их.Но ваш код должен сработать NotSupportedException
потому что это запрещено: db.LandPoints.Select(x => new LandPoint ...
Если у вас есть LandPoint
сущность, сопоставленная с помощью структуры сущностей, которую вы не можете проецировать на этот тип в Linq-to-entities.