我有一个涉及以下3个实体的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。如果对于相同的ID,我写以下内容:

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();

我拿到窗子了。

我确信我可以使用CASE语句重写它,但我觉得这更优雅。由于它的行为方式有点违反直觉,并且理解为什么它正在做它所做的事情将帮助我更好地了解linq查询如何转换为sql,我决定在这里发布一个问题。

那么,为什么它做什么呢?是否有一些除了上面的代码,将使其工作(维护UNION语句)?

提前致谢 约翰

有帮助吗?

解决方案

这是因为union不保证订购。您不能根据项目的顺序放置任何特殊的期望而不订购它们。但你的代码应该火 NotSupportedException 因为这是不允许的: db.LandPoints.Select(x => new LandPoint ...

如果你有 LandPoint 实体框架映射的实体您无法在Linq-to-entities中投影到此类型。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top