【问题标题】:Linq : select value in a datatable columnLinq:在数据表列中选择值
【发布时间】:2009-12-10 10:48:52
【问题描述】:

如何使用LINQ (C#)datatable 中的特定行选择特定列中的值。等效的SQL 将是:

select NAME from TABLE where ID = 0

提前致谢。

【问题讨论】:

    标签: c# linq datatable


    【解决方案1】:

    感谢您的回答。我不明白“MyTable”是什么类型的对象(在你的答案中),下面的代码给了我下面显示的错误。

    DataTable dt = ds.Tables[0];
    var name = from r in dt
               where r.ID == 0
               select r.Name;
    

    找不到源类型的查询模式的实现 '系统.数据.数据表'。找不到“哪里”

    所以我继续我的谷歌搜索,发现了一些有用的东西:

    var rowColl = ds.Tables[0].AsEnumerable();
    string name = (from r in rowColl
                  where r.Field<int>("ID") == 0
                  select r.Field<string>("NAME")).First<string>();
    

    你怎么看?

    【讨论】:

    • 如果你想使用 '.AsEnumerable' 一定要添加 dll 'System.Data.DataSetExtensions' 和一个 using 语句!
    • 上面的修订评论:如果你想使用'.AsEnumerable',请务必添加 dll 'System.Data.DataSetExtensions'!不要为它添加 using 语句!只需使用 System.Data 并为 .dll 提供参考即可使其正常工作。
    • 请注意AsEnumerable 将切换查询的上下文,因此您的where/select 将在内存中执行,而不是在数据库端。
    【解决方案2】:
    var name = from r in MyTable
                where r.ID == 0
                select r.Name;
    

    如果该行是唯一的,那么您甚至可以这样做:

    var row = DataContext.MyTable.SingleOrDefault(r => r.ID == 0);
    var name = row != null ? row.Name : String.Empty;
    

    【讨论】:

    • 值得注意的是,调用 SingleOrDefault 调用实际上会选择所有已翻译成 SQL 的列(因为它返回的是 MyTable 对象而不是 IQueryable)。取决于表中的其他内容可能会对 select 方法不会产生的性能影响。在典型的表上,可读性可以说值得微小的性能差异,但由于问题是关于等效 SQL,我认为值得澄清。
    • SingleOrDefault 最适合用于从集合中检索唯一项目的情况。听上去 OP 是哪个。
    【解决方案3】:

    我注意到其他人已经给出了非 lambda 语法,所以为了完成这个,我将放入等效的 lambda 语法:

    非 lambda(根据 James 的帖子):

    var name = from i in DataContext.MyTable
               where i.ID == 0
               select i.Name
    

    等效的 lambda 语法:

    var name = DataContext.MyTable.Where(i => i.ID == 0)
                                  .Select(i => new { Name = i.Name });
    

    实际上并没有太大的区别,只是您喜欢的个人意见。

    【讨论】:

    • 我认为您的 lambda 答案比标记的答案正确。 SingleOrDefault() 将获取该行的所有列(这不是 OP 要求的,OP 只要求一列)。 Where() 和 Select() 组合只会获取所需的列,而不是获取所有列。如果我错了,请纠正我。
    • 是的,你是对的。当然,您仍然可以在最后执行“.SingleOrDefault()”(例如:string name = DataContext.MyTable.Where(i =&gt; i.ID == 0).Select(i =&gt; i.Name).SingleOrDefault(); 只会向后查询 1 列)。 SingleOrDefault 本质上没有什么“获取所有”的东西,您只需要为此链接查询。话虽如此,除非您在其他列中有一些非常大的数据,否则性能开销通常可以忽略不计。
    【解决方案4】:

    如果返回值是字符串,需要按Id搜索,可以使用:

    string name = datatable.AsEnumerable().Where(row => Convert.ToInt32(row["Id"]) == Id).Select(row => row.Field<string>("name")).ToString();
    

    或使用泛型变量:

    var name = datatable.AsEnumerable().Where(row => Convert.ToInt32(row["Id"]) == Id).Select(row => row.Field<string>("name"));
    

    【讨论】:

    • 也可以使用:string name = datatable.AsEnumerable().Where(row => Convert.ToInt32(row["Id"]) == Id).Select(row => row.字段("name")).First();
    • 致 mbaddeveloper:如果您只是想从一行中获取一个字段,那么关于 first 的评论非常重要。效果很好!
    【解决方案5】:
    var name = from DataRow dr in tblClassCode.Rows where (long)dr["ID"] == Convert.ToInt32(i) select (int)dr["Name"]).FirstOrDefault().ToString() 
    

    【讨论】:

      【解决方案6】:
      var x  =  from row in table
                where row.ID == 0
                select row
      

      假设您有一个知道行的 DataTable,否则您将需要使用行索引:

      where row[rowNumber] == 0
      

      在这种情况下,您还想使用 select 将行数据放入匿名类或预先准备好的类中(如果您想将其传递给另一个方法)

      【讨论】:

        【解决方案7】:

        使用 linq 并将数据表设置为 Enumerable 并从数据表字段中选择与您要查找的内容匹配的字段。

        示例

        我想从货币为本地货币的货币表中获取货币 ID 和货币名称,并将货币 ID 和名称分配给表单上的文本框:

        DataTable dt = curData.loadCurrency();
                    var curId = from c in dt.AsEnumerable()
                                where c.Field<bool>("LocalCurrency") == true
                                select c.Field<int>("CURID");
        
                    foreach (int cid in curId)
                    {
                        txtCURID.Text = cid.ToString();
                    }
                    var curName = from c in dt.AsEnumerable()
                                  where c.Field<bool>("LocalCurrency") == true
                                  select c.Field<string>("CurName");
                    foreach (string cName in curName)
                    {
                        txtCurrency.Text = cName.ToString();
                    }
        

        【讨论】:

          猜你喜欢
          • 2021-05-01
          • 1970-01-01
          • 2021-11-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多