Sql server 我有一个带有UNION的SQL视图,当通过实体框架使用时,结果是错误的。为什么?

Sql server 我有一个带有UNION的SQL视图,当通过实体框架使用时,结果是错误的。为什么?,sql-server,entity-framework,Sql Server,Entity Framework,因此,我的ASP.NET MVC4应用程序使用EF。对于我的具体情况,我选择在SQL视图中实现部分逻辑,在EF中实现其余逻辑。这是我们以前成功使用过的一种方法:尽可能多地使用EF,但在视图中使用TSQL进行逻辑处理,这在TSQL中似乎比在EF中更容易。以下是我的TSQL视图: SELECT P.DeviceID, P.PhoneNumber, E.FullName, Effective FROM PhoneNumbers P INNER JOIN Devices D ON D .D

因此,我的ASP.NET MVC4应用程序使用EF。对于我的具体情况,我选择在SQL视图中实现部分逻辑,在EF中实现其余逻辑。这是我们以前成功使用过的一种方法:尽可能多地使用EF,但在视图中使用TSQL进行逻辑处理,这在TSQL中似乎比在EF中更容易。以下是我的TSQL视图:

SELECT P.DeviceID, P.PhoneNumber, E.FullName, Effective  
FROM PhoneNumbers P 
    INNER JOIN Devices D ON D .DeviceID = P.DeviceID 
    LEFT OUTER JOIN vEmployees E ON P.AssignedEmployeeNumber = E.EmployeeID
UNION
SELECT H.DeviceID, H.PhoneNumber, E.FullName, MIN(Effective) AS Effective
FROM PhoneNumberHistory H 
    INNER JOIN Devices D ON D .DeviceID = H.DeviceID 
    LEFT OUTER JOIN vEmployees E ON H.AssignedEmployeeNumber = E.EmployeeID
GROUP BY H.DeviceID, H.PhoneNumber, E.FullName
我的服务代码中没有太多调用EF的内容:

return this.deviceHistoryRepository.GetMany(d => d.DeviceID == id)
           .OrderByDescending(d => d.Effective).ToList();

天真地说,我希望在直接从SQL运行视图时(当然使用WHERE子句来指定DeviceID)以及通过调用EF返回相同的数据。但是相反,EF的结果有缺失行和重复行。有什么我遗漏的吗?在我的视图中,我还可以向我的TSQL添加其他内容,以便EF能够正确使用它?

是的,事实证明确实存在(我可以在我的视图中向我的SQL添加一些内容,以便EF能够正确使用它)。EF需要一个唯一的、不可为空的键来正确处理视图的结果

SELECT ISNULL(ROW_NUMBER() OVER(ORDER BY (SELECT 0)), -1) AS DeviceHistoryID, *
FROM (
    -- original TSQL from above --
) AS XYZ 

因为我使用EF对视图的结果进行排序和操作,所以我不关心视图中的顺序。但是OVER子句需要ORDER BY,所以“选择0”。为什么我要将子查询别名为XYZ?如果没有别名,即使没有使用别名,TSQL也会因语法错误而阻塞。ISNULL向EF发出信号,表示该列应标记为实体键。(如果没有这样标记,返回的结果可能不正确。)

虽然我已经回答了自己的问题,但我希望得到更好的答案。要么是一个更干净的解决方案,要么是对我的解决方案进行更深入的解释。谢谢。出于好奇,有什么令人信服的理由必须像这样在篮球场上跳舞?为什么不直接使用.Net SqlClient访问视图呢?因为EF在绝大多数情况下都可以工作,并且节省了大量的编码工作。只有这样的角落案例才会变得混乱,而且只有在第一次遇到它们时才会变得混乱。“hoop”是三行样板TSQL。“回退位置”可能是在存储过程中使用EF,而不是放弃SqlClient的EF。