3

所以我的 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 可以正确使用它?

4

1 回答 1

1

是的,事实证明有(我可以在我的视图中添加到我的 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,所以“SELECT 0”。为什么我将子查询别名为 XYZ?如果没有别名,即使没有使用别名,TSQL 也会出现语法错误。ISNULL 向 EF 发出信号,表明该列应标记为实体键。(如果没有这样标记,返回的结果可能不正确。)

于 2013-09-19T00:54:33.647 回答