sql-server - 我有一个带有 UNION 的 SQL View ,当通过 Entity Framework 使用时,结果是错误的。为什么?

标签 sql-server entity-framework

所以我的 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/

相关文章:

c# - EntityFramework 6 现有数据库和新数据库的迁移?

sql-server - 将数据类型 nvarchar 转换为数字异常时出错

sql-server - 可复制的 Coldfusion SQL 异常

sql - 动态 SQL 查询字符串截断为 256 个字符

sql-server - SQL Server 中的总和?

.net - 表达式树中的类似运算符

c# - 使用字节作为主键数据类型

entity-framework - 在查询中使用 FirstOrDefault()

sql-server - 无法连接到 Azure VM 上的 SQL Server

asp.net-mvc - 无法从应用程序连接到 SQL Azure,但可以从 SSMS 连接到 SQL Azure