EF5联盟没有按预期工作
-
11-12-2019 - |
题
我有一个涉及以下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中投影到此类型。
不隶属于 StackOverflow