在LINQ中等价于SQL ISNULL ?

时间:2022-01-19 15:46:47

In SQL you can run a ISNULL(null,'') how would you do this in a linq query?

在SQL中,您可以运行一个ISNULL(null,”),您如何在linq查询中执行这个操作?

I have a join in this query:

我加入了这个查询:

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
        };

but I have a column that has a bit type that is non nullable (xx.online) how can I set this to false if it is null?

但是我有一个具有非nullable (xx.online)的位类型的列,如果它是null,我如何将它设为false ?

4 个解决方案

#1


56  

Since aa is the set/object that might be null, can you check aa == null ?

既然aa是可能为空的集合/对象,你能检查aa == null吗?

(aa / xx might be interchangeable (a typo in the question); the original question talks about xx but only defines aa)

(aa / xx可能是可互换的(问题中的错误);原来的问题是关于xx的,但是只定义aa)

i.e.

即。

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

or if you want the default to be false (not null):

或者,如果您希望默认值为false(非空):

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

Update; in response to the downvote, I've investigated more... the fact is, this is the right approach! Here's an example on Northwind:

更新;作为对投票结果的回应,我调查了更多……事实是,这是正确的做法!这里有一个关于北风的例子:

        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);
            }
        }

And here's the TSQL - pretty much what we want (it isn't ISNULL, but it is close enough):

这是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?

QED吗?

#2


23  

You can use the ?? operator to set the default value but first you must set the Nullable property to true in your dbml file in the required field (xx.Online)

你可以用??操作符要设置默认值,但首先必须在必需字段(xx.Online)的dbml文件中将Nullable属性设置为true

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
        };

#3


1  

I often have this problem with sequences (as opposed to discrete values). If I have a sequence of ints, and I want to SUM them, when the list is empty I'll receive the error "InvalidOperationException: The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.".

我经常在序列上遇到这个问题(与离散值相反)。如果我有一个ints序列,并且我想对它们进行求和,当列表为空时,我将收到错误“InvalidOperationException: null值不能分配给具有类型系统的成员。它是一个不可空值类型。

I find I can solve this by casting the sequence to a nullable type. SUM and the other aggregate operators don't throw this error if a sequence of nullable types is empty.

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

So for example something like this

举个例子

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

becomes

就变成了

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

The second one will return 0 when no rows match the where clause. (the first one throws an exception when no rows match).

当没有行与where子句匹配时,第二个将返回0。(第一个在没有行匹配时抛出异常)。

#4


0  

Looks like the type is boolean and therefore can never be null and should be false by default.

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

#1


56  

Since aa is the set/object that might be null, can you check aa == null ?

既然aa是可能为空的集合/对象,你能检查aa == null吗?

(aa / xx might be interchangeable (a typo in the question); the original question talks about xx but only defines aa)

(aa / xx可能是可互换的(问题中的错误);原来的问题是关于xx的,但是只定义aa)

i.e.

即。

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

or if you want the default to be false (not null):

或者,如果您希望默认值为false(非空):

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

Update; in response to the downvote, I've investigated more... the fact is, this is the right approach! Here's an example on Northwind:

更新;作为对投票结果的回应,我调查了更多……事实是,这是正确的做法!这里有一个关于北风的例子:

        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);
            }
        }

And here's the TSQL - pretty much what we want (it isn't ISNULL, but it is close enough):

这是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?

QED吗?

#2


23  

You can use the ?? operator to set the default value but first you must set the Nullable property to true in your dbml file in the required field (xx.Online)

你可以用??操作符要设置默认值,但首先必须在必需字段(xx.Online)的dbml文件中将Nullable属性设置为true

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
        };

#3


1  

I often have this problem with sequences (as opposed to discrete values). If I have a sequence of ints, and I want to SUM them, when the list is empty I'll receive the error "InvalidOperationException: The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.".

我经常在序列上遇到这个问题(与离散值相反)。如果我有一个ints序列,并且我想对它们进行求和,当列表为空时,我将收到错误“InvalidOperationException: null值不能分配给具有类型系统的成员。它是一个不可空值类型。

I find I can solve this by casting the sequence to a nullable type. SUM and the other aggregate operators don't throw this error if a sequence of nullable types is empty.

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

So for example something like this

举个例子

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

becomes

就变成了

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

The second one will return 0 when no rows match the where clause. (the first one throws an exception when no rows match).

当没有行与where子句匹配时,第二个将返回0。(第一个在没有行匹配时抛出异常)。

#4


0  

Looks like the type is boolean and therefore can never be null and should be false by default.

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