所以我的 ASP.NET MVC4 应用程序使用 EF。对于我的具体情况,我选择在 SQL View 中实现部分逻辑,而在 EF 中实现其余部分。这是我们以前成功使用过的一种方法:尽可能多地使用 EF,但在 View 中使用 TSQL 进行逻辑处理,这在 TSQL 中似乎比在 EF 中更容易。这是我的 TSQL View :
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 运行 View (当然有一个 WHERE 子句,以指定 DeviceID)和通过调用 EF 返回相同的数据。但是,EF 的结果却缺少行和重复行。有什么我想念的吗?我可以在我的 View 中添加其他内容到我的 TSQL,以便 EF 可以正确使用它吗?
最佳答案
是的,事实证明有(我可以在我的 View 中添加一些东西到我的 SQL 中,以便 EF 可以正确使用它)。 EF 需要一个唯一的、不可为 null 的键来正确处理 View 的结果。
SELECT ISNULL(ROW_NUMBER() OVER(ORDER BY (SELECT 0)), -1) AS DeviceHistoryID, *
FROM (
-- original TSQL from above --
) AS XYZ
由于我使用 EF 对 View 的结果进行排序和操作,所以我不关心 View 中的顺序。但是 OVER 子句需要一个 ORDER BY,所以“SELECT 0”。为什么我将子查询别名为 XYZ?如果没有别名,即使没有使用别名,TSQL 也会因语法错误而阻塞。 ISNULL 向 EF 发出信号,表明此列应标记为实体键。 (如果没有这样标记,返回的结果可能不正确。)
关于sql-server - 我有一个带有 UNION 的 SQL View ,当通过 Entity Framework 使用时,结果是错误的。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18884655/