2013-11-20 61 views
1

我有以下表格:SQL返回数据,但相应的LINQ语句返回没有数据

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

EventLogs 
    ... 
    UserID (varchar) 
    ... 

下面的SQL语句返回2行数据,因为这些是仅有的2个运营商有在事件日志时表中的数据:

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返回同一2个结果SQL和使用该工具Linqer一个不同的结果中的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' 

的LINQ

(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转换为字符串原来的尝试。

+0

实际上,您是否在'UserID'列中将值为NULL的行存储为字符串文字? –

+0

@ martin-smith是的。如果没有UserID(OperatorId)插入,则在插入EventLog条目时,NULL是默认值。不是我的选择。只是与我的工作。 – iamchrisfryer

+0

您是否允许创建存储过程?如果是这样,你可以使用工作的SQL,然后用LINQ调用存储过程。这可能会简化您的代码。我并不总是这样建议,但是您正处于LINQ难以完成的情况。 –

回答

0

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

SqlFunctions.StringConvert((double)o.OperatorId) 

在C#相当于

STR(CAST(OperatorId AS float)) 

在SQL。

SQL中生成的float值包含前导和尾随空白。

所以

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空白并返回预期值。