【问题标题】:LINQ and column with NullLINQ 和带有 Null 的列
【发布时间】:2017-12-11 11:07:06
【问题描述】:

我有一个DataSet,有一个列,我们称之为A,类型为Int。我想在 A 列上使用 where 运行一个简单的 LINQ 查询。问题是,该列 A 可以包含空值(至少在我得到它的T-SQL 表中,我不确定这些空值是如何在TableAdapter 中转换的)。当我尝试运行以下查询时,这会导致错误:

MyTableDataTable dt =
    new MyTableDataTable();

MyTableTableAdapter ta =
     new MyTableTableAdapter();

        ta.Fill(dt);

// This is where the error occurs
var query = from  tbl in dt.AsEnumerable()
            where tbl.A == parentId 
            &&    tbl.B == languageId
            select new
            {
                tbl.A,
                tbl.B,
                tbl.C
            };

它返回的错误信息是这样的:

StrongTypingException 未处理

未处理的类型异常 'System.Data.StrongTypingException' 发生在 我的程序.exe

附加信息:“A”列的值 表 'MyTable' 是 DBNull。

nullvalues 在这样的场景下应该如何上交?我想做where A is not null之类的事情,但我真的找不到办法……

【问题讨论】:

  • 你想做where tbl.A != null?听起来很容易... :)
  • 由于值为 DBNull where tbl.A != DbNull.Value
  • @Magnus 导致语法错误:“运算符 '!=' 不能应用于 'int' 和 'DBNull' 类型的操作数”
  • 在这种情况下,tbl.A 永远不会是null
  • 在这种情况下,错误一定来自ta.Fill(dt); 可能dataTable 列Aint 但应该是int?

标签: c# sql-server linq tsql dataset


【解决方案1】:

你提到 Anullable,所以我假设在你的定义中你有类似的东西:

int? A { get; set; }

或类似的东西。注意 (?) 使属性可以为空。如果设置好了,那么你可以这样做:

var query = from  tbl in dt.AsEnumerable()
            where tbl?.A == parentId 
            &&    tbl.B == languageId
            select new
            {
                tbl.A,
                tbl.B,
                tbl.C
            };

还要注意属性 A 之前的 (?)。另一种方法是使用ternary operation 方法,例如:

var query = from  tbl in dt.AsEnumerable()
            where tbl.A == null ? true : tbl.A == parentId
            &&    tbl.B == languageId
            select new
            {
                tbl.A,
                tbl.B,
                tbl.C
            };

如果属性 A 为 null,则解析为 true 并跳至下一个条件。

【讨论】:

  • 我没有尝试更改数据集,我认为我需要尝试您的解决方案。但是,我认为您正在解决正确的问题。也就是说,虽然 A 在数据库中可以为空,但我不认为它在数据集中以同样的方式可以为空。也许如果我将数据类型更改为int? 而不是int,它会起作用。
  • 是的,因为 A 在数据库中是可空的,我认为将它与数据集上的可空匹配也很重要。你是对的,如果 A 被明确定义为可空(在数据集上),我的解决方案将起作用。尝试后告诉我。
  • 我对@9​​87654328@ 使用了拖放设计,这可能不是最好的方法。如果我重新访问DataSet 设计并尝试您的解决方案,我会通知您。感谢您的意见。
【解决方案2】:

试用代码:

var query = from  tbl in dt.AsEnumerable()
        where tbl.Field<dynamic>("A") == parentId 
        &&    tbl.Field<dynamic>("B") == languageId
        select tbl;

【讨论】:

    【解决方案3】:

    我在尝试@ gencklavyeler的建议时偶然发现了一个解决方案。 tbl.A != null不起作用,而另一种方式使用tbl.IsANull() == false。像这样:

    var query = from  tbl in dt.AsEnumerable()
                where tbl.IsANull() == false
                &&    tbl.A == parentId 
                &&    tbl.B == session.LanguageId
                select new
                {
                    tbl.A,
                    tbl.B,
                    tbl.C
                };
    

    【讨论】:

    • 嗨@noceo,你也试试答案吗? span>
    • 虽然,它比我更加多样化。主要是int? int讨论。因此,虽然此方法解决了问题,但我建议您也建议阅读其他帖子... span>
    【解决方案4】:

    tbl.A == parentId前必须勾选null,有福利勾选tbl.B

    var query = from  tbl in dt.AsEnumerable()
            where tbl.A != null && tbl.A == parentId 
            &&  tbl.B != null &&  tbl.B == languageId
            select new
            {
                tbl.A,
                tbl.B,
                tbl.C
            };
    

    【讨论】:

    • 如果我这样做,我会在那条线上发出警告,说:“因为类型'int'的值永远不会等于'null'的'true',因此该表达式的结果是'true'。 int?“” span>
    • @ noceo是tbl.B也为空?如果不是,您只需使用tbl.B == languageId而无需检查null span>
    • @AleksAndreev tbl.B 不能让我为空,所以问题只与列 A 有关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-29
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多