【问题标题】:How to convert a LINQ query result to a DataTable dynamically?如何将 LINQ 查询结果动态转换为 DataTable?
【发布时间】:2014-10-31 13:45:42
【问题描述】:

如何将 LINQ 查询结果动态转换为 DataTable?

有一些解决方案,您可以创建另一个类并指定列名,但我希望能够灵活地更改 LINQ 结构,例如列名、列数量,并使用列名自动生成 DataTable。

谢谢

【问题讨论】:

    标签: c# .net linq datatable lambda


    【解决方案1】:

    我已经包含了一个与 SqlBulkCopy 一起使用的扩展方法,它应该可以完成这项工作,但我想问一下您为什么要进行这种转换。在非常有限的情况下(SqlBulkCopy 是一个),对象列表不能完成数据表可以做的所有事情。您可以将它们用作大多数控件的绑定源……只是好奇。

    public static DataTable toDataTable<T>(this IEnumerable<T> value, List<string> exclusionList)
            where T : class
        {
            var dataTable = new DataTable();
    
            var type = typeof(T);
    
            var properties = type.GetProperties().Where(x =>  !exclusionList.Contains(x.Name)).ToList();
    
            foreach (var propertyInfo in properties)
            {
                var propertyType = propertyInfo.PropertyType;
                if (!propertyType.IsScalar())
                    continue;
    
                var nullableType = Nullable.GetUnderlyingType(propertyType);
                propertyType = nullableType ?? propertyType;
    
                var dataColumn = new DataColumn(propertyInfo.Name, propertyType);
    
                if (nullableType != null)
                    dataColumn.AllowDBNull = true;
    
                dataTable.Columns.Add(dataColumn);
            }
    
            foreach (var row in value)
            {
                var dataRow = dataTable.NewRow();
    
                foreach (var property in properties)
                {
                    var safeValue = property.GetValue(row, null) ?? DBNull.Value;                    
                    dataRow[property.Name] = safeValue;
                }
    
                dataTable.Rows.Add(dataRow);
            }
    
            return dataTable;
        }
    

    【讨论】:

    • 假设您有一个库中的类,它使用 LINQ 从数据库中检索信息,您希望返回结果,因此不同类型的项目,如 Windows 窗体 (DataGridView)、Web 窗体 (GridView) 可以显示信息,您不能返回匿名类型的列表。我试图使用你的扩展,但我不知道 IsScalar() 是在哪里声明的。
    • 标量是否在另一个库中,你可以把它拉出来
    【解决方案2】:

    查看MoreLinq Nuget 包。它有一个函数ToDataTable()

    var LinqResults = from ......;
    DataTable dt_Results = LinqResults.ToDataTable();
    

    https://code.google.com/p/morelinq/

    它还有其他非常有用的功能: https://code.google.com/p/morelinq/wiki/OperatorsOverview

    【讨论】:

      【解决方案3】:

      他们的关键是使用 LINQ 查询结果作为其实现的 IList 接口。 如果您将结果作为 IList 对象的方法的参数接收,则可以通过以下方式访问其列和行:

      var props = item.GetType().GetProperties();
      

      参考这个例子,它是一个小类,请注意它只是抽象了DataTable的创建,并且里面有一个名为“LINQToDataTable”的静态方法,你应该使用它。

      1. 第一步,创建一个名为“GridHelper”的类(DataTable结构使用System.Data)

        public class GridHelper
        {
        private DataTable baseDt;
        
        public GridHelper(string tableName)
        {
            baseDt = new DataTable(tableName);
        }
        
        
        public DataTable getDataTable()
        {
            return baseDt;
        }
        
        public object[,] getObjToFill()
        {
            object[,] obj = new object[baseDt.Columns.Count, 2];
            for (int i = 0; i < baseDt.Columns.Count; i++)
            {
                obj[i, 0] = baseDt.Columns[i].ColumnName;
            }
        
            return obj;
        }
        
        public void addColumn(string colName, Type valueType)
        {
            baseDt.Columns.Add(colName, valueType);
        }
        
        public void addRow(object[,] values)
        {
        
            DataRow newRow = baseDt.NewRow();
        
            for (int i = 0; i < values.Length / 2; i++)
            {
                bool colFound = false;
        
                for (int j = 0; j < baseDt.Columns.Count; j++)
                {
                    if (baseDt.Columns[j].ColumnName == values[i, 0].ToString())
                    {
                        colFound = true;
                        break;
                    }
                }
                if (colFound == false)
                {
                    throw new Exception("The column " + values[i, 0].ToString() + " has not been added yet.");
                }
        
                newRow[values[i, 0].ToString()] = values[i, 1];
            }
        
            baseDt.Rows.Add(newRow);
        
        }
        
        
        public static DataTable LINQToDataTable<T>(T objToList) where T : System.Collections.IList
        {
        
        
            GridHelper ghResult = new GridHelper("Report");
        
        
            foreach (Object item in objToList)
            {
                var props = item.GetType().GetProperties();
        
                foreach (var prop in props)
                {
                    ghResult.addColumn(prop.Name, typeof(string));
                    //prop.Name
                    //prop.GetValue(item)
                }
        
                break;
            }
        
            object[,] obj = ghResult.getObjToFill();
        
        
        
        
            foreach (Object item in objToList)
            {
                var props = item.GetType().GetProperties();
                int index = 0;
                foreach (var prop in props)
                {
                    //ReportValue(prop.Name, prop.GetValue(item, null));
                    //prop.Name
                    obj[index, 1] = prop.GetValue(item);
                    index++;
                }
        
                ghResult.addRow(obj);
            }
        
        
            return ghResult.getDataTable();
        }
        
        
        
        }
        
      2. 用法:

            var listaReporte =
                (from t in dbContext.TablaPruebas
                 select new
                 {
                     Name = t.name,
                     Score = t.score
                 }
                ) .ToList();
        
            DataTable dt = Library.GridHelper.LINQToDataTable(listaReporte);
        
      3. 也就是说,在 GridView 或 DataGridView 上随意使用 DataTable

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-12
        • 1970-01-01
        • 1970-01-01
        • 2012-07-05
        • 1970-01-01
        • 2011-03-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多