Вопрос

У меня есть запрос 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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top