2009-01-05 51 views
48

在SQL中,你可以运行一个ISNULL(null,'')你将如何在linq查询中做到这一点?LINQ中SQL ISNULL的等价物?

我有一个在此查询联接:

var hht = from x in db.HandheldAssets 
     join a in db.HandheldDevInfos on x.AssetID equals a.DevName into DevInfo 
     from aa in DevInfo.DefaultIfEmpty() 
     select new 
     { 
     AssetID = x.AssetID, 
     Status = xx.Online 
     }; 

,但我有一个位类型为非可空(xx.online)我怎么可以将其设置为false,如果它是空列?

+3

你的意思是“aa.Online”? “xx”没有在任何地方定义... – 2009-01-05 14:35:24

回答

55

由于aa是集/可能为空的对象,你可以检查aa == null

aa/xx可能互换(在这个问题一个错字);原来的问题谈到xx但只定义aa

select new { 
    AssetID = x.AssetID, 
    Status = aa == null ? (bool?)null : aa.Online; // a Nullable<bool> 
} 

,或者如果你希望默认是false(不null):

select new { 
    AssetID = x.AssetID, 
    Status = aa == null ? false : aa.Online; 
} 

更新;为了回应downvote,我调查了更多......事实是,这是正确的做法!下面是关于罗斯文一个例子:

 using(var ctx = new DataClasses1DataContext()) 
     { 
      ctx.Log = Console.Out; 
      var qry = from boss in ctx.Employees 
         join grunt in ctx.Employees 
          on boss.EmployeeID equals grunt.ReportsTo into tree 
         from tmp in tree.DefaultIfEmpty() 
         select new 
          { 
           ID = boss.EmployeeID, 
           Name = tmp == null ? "" : tmp.FirstName 
         }; 
      foreach(var row in qry) 
      { 
       Console.WriteLine("{0}: {1}", row.ID, row.Name); 
      } 
     } 

而这里的TSQL - 几乎是我们想要的东西(它不是ISNULL,但它是足够接近):

SELECT [t0].[EmployeeID] AS [ID], 
    (CASE 
     WHEN [t2].[test] IS NULL THEN CONVERT(NVarChar(10),@p0) 
     ELSE [t2].[FirstName] 
    END) AS [Name] 
FROM [dbo].[Employees] AS [t0] 
LEFT OUTER JOIN (
    SELECT 1 AS [test], [t1].[FirstName], [t1].[ReportsTo] 
    FROM [dbo].[Employees] AS [t1] 
    ) AS [t2] ON ([t0].[EmployeeID]) = [t2].[ReportsTo] 
-- @p0: Input NVarChar (Size = 0; Prec = 0; Scale = 0) [] 
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 3.5.30729.1 

QED?

0

看起来类型是布尔型的,因此永远不能为空,默认情况下应该为false。

+1

如果它来自一个连接,你怎么能使它默认为false? – MartGriff 2009-01-05 13:51:56

+0

肯定会默认为false?它是一个布尔值并且尚未设置,所以它应该是false。你在看什么? – 2009-01-05 14:00:56

23

可以使用??操作员设置的默认值,但首先你必须在必填字段设置Nullable属性true的dbml文件(xx.Online

var hht = from x in db.HandheldAssets 
     join a in db.HandheldDevInfos on x.AssetID equals a.DevName into DevInfo 
     from aa in DevInfo.DefaultIfEmpty() 
     select new 
     { 
     AssetID = x.AssetID, 
     Status = xx.Online ?? false 
     }; 
1

我经常遇到序列问题(与离散值相反)。如果我有一个整数序列,并且我希望SUM它们,当列表为空时,我将收到错误“InvalidOperationException:无法将null值分配给类型为System.Int32的成员,该成员是非空值类型。”。

我发现我可以通过将序列强制转换为可空类型来解决此问题。如果一个可为空的类型序列为空,则SUM和其他聚合运算符不会抛出此错误。

因此,例如,像这样

MySum = MyTable.Where(x => x.SomeCondtion).Sum(x => x.AnIntegerValue); 

成为

MySum = MyTable.Where(x => x.SomeCondtion).Sum(x => (int?) x.AnIntegerValue); 

第二个将返回0时没有行的where子句相匹配。 (当没有行匹配时,第一个引发异常)。