【问题标题】:SQL returns data but the corresponding Linq statement returns no dataSQL 返回数据但对应的 Linq 语句没有返回数据
【发布时间】:2013-11-22 02:34:33
【问题描述】:

我有以下表格:

Operators
    OperatorId (int)
    Username (varchar)
    IsActive (bit)

EventLogs
    ...
    UserID (varchar)
    ...

以下 SQL 语句返回 2 行数据,因为它们是仅有的 2 个在 EventLogs 表中具有数据的 Operator:

select distinct o.OperatorId, o.Username, o.IsActive
from Operators o
join EventLogs e on CAST(o.OperatorId AS VARCHAR) = e.UserID
where e.UserID != 'NULL'

使用Linqer,它产生了以下Linq语句:

(from o in db.Operators
join e in db.EventLogs on SqlFunctions.StringConvert((Double)o.OperatorId) equals e.UserID
where
    e.UserID != "NULL"
select new {
    o.OperatorId,
    o.Username,
    o.IsActive
}).Distinct()

我很难理解和编写正确的 Linq 语句以返回相同的信息。

我尝试将 e.UserID 转换为 INT,它使用 Linqer 工具在 SQL 中返回相同的 2 个结果,在 Linq 中返回不同的结果:

SQL

select distinct o.OperatorId, o.Username, o.IsActive
from Operators o
join EventLogs e on o.OperatorId = CAST(e.UserID AS INT)
where e.UserID != 'NULL'

灵巧

(from o in db.Operators
join e in db.EventLogs on new { OperatorId = o.OperatorId } equals new { OperatorId = (int?)(int)(Int32)e.UserID }
where
      e.UserID != "NULL"
select new {
      OperatorId = (int?)o.OperatorId,
      o.Username,
      o.IsActive
}).Distinct()

不同的是,这个 Linq 甚至不编译。

使用The type arguments cannot be inferred from the query. 加入失败,(Int32) 转换失败并使用Cannot cast expression of type 'string' to type 'int'

我对使用 SqlFunctions.StringConvert 将 o.OperatorId 转换为字符串的原始尝试很好。

【问题讨论】:

  • 您实际上是否将具有值NULL 的行作为字符串文字存储在UserID 列中?
  • @martin-smith 是的。 NULL 是在没有要插入的 UserID (OperatorId) 时插入 EventLog 条目时的默认值。不是我的选择。只使用我所拥有的。
  • 是否允许创建存储过程?如果是这样,您可以使用工作 SQL,然后使用 LINQ 调用存储过程。它可能会简化您的代码。我并不总是建议这样做,但您可能会遇到 LINQ 难以完成的情况。

标签: c# sql sql-server linq


【解决方案1】:

我很幸运能够运行 SQL Profiler,因为这是一个开发服务器。

SqlFunctions.StringConvert((double)o.OperatorId) 

在 C# 中相当于

STR( CAST( OperatorId AS float))

在 SQL 中。

SQL 中生成的浮点值包含前导和尾随空格。

所以

WHERE (N'1' = (STR( CAST( [Extent1].[OperatorId] AS float)))) OR (N'2' = (STR( CAST( [Extent1].[OperatorId] AS float))))

除非 SQL 包含 LTRIMRTRIM 包裹在 CAST 周围,否则将找不到匹配项

通过在 C# Linq 中添加 SqlFunctions.StringConvert((double)o.OperatorId).Trim(),它会修剪结果 SQL 中的空白并返回预期值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 2022-11-01
    • 2011-10-26
    • 2011-06-06
    相关资源
    最近更新 更多