Linq语句返回除字符串类型以外的所有列过滤器的最大长度

本文关键字:过滤器 Linq 返回 字符串 类型 语句 | 更新日期: 2023-09-27 18:12:51

List<int> maximumLengthForColumns =
    Enumerable.Range(0, dt.Columns.Count)
              .Select(col => dt.AsEnumerable()
                               .Select(row => row[col])
                               .OfType<string>()
                               .Max(val => val.Length)
                      ).ToList();

Linq语句查找数据表中所有列的最大长度。谁能帮我把列类型上的where子句。如果列类型不是字符串,则会产生异常。

Linq语句返回除字符串类型以外的所有列过滤器的最大长度

我不认为Linq语句会工作。试试这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Data;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            List<int> maximumLengthForColumns = new List<int>(dt.Columns.Count);
            foreach (DataRow row in dt.AsEnumerable())
            {
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    if (row[i].GetType() == typeof(string))
                    {
                        int length = row.Field<string>(i).Count();
                        if (length > maximumLengthForColumns[i])
                            maximumLengthForColumns[i] = length; 
                    }
                }
            }
        }
    }
}
​

合理复杂的嵌入式LINQ查询系列来实现这一点。

给定以下示例数据-

DataTable dtb = new DataTable();
dtb.Columns.Add(new DataColumn() { DataType = typeof(string) });
dtb.Columns.Add(new DataColumn() { DataType = typeof(int) });
dtb.Columns.Add(new DataColumn() { DataType = typeof(bool) });
dtb.Columns.Add(new DataColumn() { DataType = typeof(string) });

dtb.Rows.Add(new object[] { "dave", 1, true, "sanderson" });
dtb.Rows.Add(new object[] { "oliver", 1, true, "brown" }); 

下面的LINQ子句将返回一个整数List(6和9),它们对应于列1和列4(唯一的数据类型为string的列)的最大数据长度。

var answer =
    (from a in
         (from row in dtb.AsEnumerable() //get all the data rows
          select
               (from col in //filter the columns in i.e. just string ones
                     (from column in dtb.Columns.Cast<DataColumn>() 
                     where column.DataType == typeof(string)
                     select column.Ordinal)
               //build an array holding relavent data i.e. just string values
                select new { col = col, val = row[col] }).ToArray())
                //flaten the data into a single data set
                .SelectMany(m => (from a in m select new { col = a.col, a.val })) 
                group a by a.col into g //group the data by the column
                //as we have grouped by column we can now max the string data's length  
                select g.Max(s => s.val.ToString().Length)).ToList(); 

然而,把它们分开会让它更容易读。

 //get the string columns from the datatable
 var cols = (from column in dtb.Columns.Cast<DataColumn>()
            where column.DataType == typeof(string)
            select column).ToList();

 //get the row data from the table, using select many to finally flatten back to a flat array of data.
 var rows = (from row in dtb.AsEnumerable()
            select
            (from col in cols
             select new { col = col.Ordinal, val = row[col] }).ToArray()
            ).SelectMany(m => (from a in m select new { col = a.col, a.val })).ToList();

 //group the data by the column and get the max data length
 var answer = (from a in rows
               group a by a.col into g
               select g.Max(s => s.val.ToString().Length)).ToList();