[转载]C#.NET DataTable扩展 ToList/Get/OrderBy/Where/ToPage

本文介绍了一系列针对DataTable的扩展方法,包括转换为列表、排序、筛选等实用功能,旨在提高.NET应用程序中数据处理的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://www.cnblogs.com/livexy/archive/2010/07/06/1772213.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Data;
using System.Data.Common;
using System.Web.Script.Serialization;
using System.IO;
using System.Security.Cryptography;

namespace Pub.Class {
   
public static class DataTableExtensions {

       
public static List<TResult> ToList<TResult>(this DataTable dt) where TResult : class,new() {  
            List
<TResult> list= new List<TResult>();
           
if (dt == null) return list;
           
int len = dt.Rows.Count;

           
for (int i = 0; i < len; i++) {
                TResult info
= new TResult();
               
foreach (DataColumn dc in dt.Rows[i].Table.Columns) {
                   
if (dt.Rows[i][dc.ColumnName] == null || string.IsNullOrEmpty(dt.Rows[i][dc.ColumnName].ToString())) continue;
                    System.Reflection.PropertyInfo pi
= info.GetType().GetProperty(dc.ColumnName);
                    pi.SetValue(info, dt.Rows[i][dc.ColumnName],
null);
                }
                list.Add(info);
            }
            dt.Dispose(); dt
= null;
           
return list;
        }  
       
public static DataTable OrderBy(this DataTable dt, string orderBy) {
            dt.DefaultView.Sort
= orderBy;
           
return dt.DefaultView.ToTable();
        }
       
public static DataTable Where(this DataTable dt, string where) {
            DataTable resultDt
= dt.Clone();
            DataRow[] resultRows
= dt.Select(where);
           
foreach (DataRow dr in resultRows) resultDt.Rows.Add(dr.ItemArray);
           
return resultDt;
        }
       
public static List<TResult> OrderBy<TResult>(this DataTable dt, string orderBy) where TResult : class,new() {  
           
return dt.OrderBy(orderBy).ToList<TResult>();
        }
       
public static List<TResult> Where<TResult>(this DataTable dt, string where) where TResult : class,new() {  
           
return dt.Where(where).ToList<TResult>();
        }
       
public static List<TResult> ToPage<TResult>(this DataTable dt, int pageIndex,int pageSize,out int totalRecords) where TResult : class,new() {  
            totalRecords
= dt.Rows.Count;
           
int startRow = (pageIndex - 1) * pageSize;
           
int endRow = startRow + pageSize;
           
if (startRow > totalRecords || startRow < 0) { startRow = 0; endRow = pageSize; }
           
if (endRow > totalRecords + pageSize) { startRow = totalRecords - pageSize; endRow = totalRecords; }

            DataTable dt2
= dt.Clone();
           
for (int i = startRow; i < endRow; i++) { if (i >= totalRecords) break; dt2.Rows.Add(dt.Rows[i].ItemArray); }

           
return dt2.ToList<TResult>();
        }

       
public static T Get<T>(this DataRow row, string field) { return row.Get<T>(field, default(T)); }
       
public static T Get<T>(this DataRow row, string field, T defaultValue) {
            var value
= row[field];
           
if(value == DBNull.Value) return defaultValue;
           
return value.ConvertTo<T>(defaultValue);
        }
       
public static T Get<T>(this DataRowView row, string field) { return row.Get<T>(field, default(T)); }
       
public static T Get<T>(this DataRowView row, string field, T defaultValue) {
            var value
= row[field];
           
if(value == DBNull.Value) return defaultValue;
           
return value.ConvertTo<T>(defaultValue);
        }

    }
}

<think>我们正在处理一个关于在ASP.NET中处理或展示大量数据的图表解决方案的问题。用户希望了解适合的图表库或实现方法。 参考用户提供的引用: - 引用[1]提到AnyChart是一个轻量级的JS图表库,支持SVG/VML,适合Web开发人员创建不同类型的图表,有助于数据分析和决策。 - 引用[2]展示了ASP代码生成报告并导出到Word的示例,但这不是图表相关的。 - 引用[3]讨论了在ASP.NET WebForm中使用HighCharts图表控件的示例,特别提到了在WebForm中实现柱形图,涉及到数据库操作。 - 引用[4]提到JSON是标准格式,但有时需要处理XML,并指出图表库是否支持XML数据很重要。 用户的问题是在ASP.NET中处理或展示大量数据的图表解决方案。因此,我们需要考虑以下几点: 1. 图表库的选择:需要能够处理大量数据,并且适合在ASP.NET环境中使用。 2. 数据格式:通常使用JSON,但有时可能需要XML。 3. 实现方式:ASP.NET有WebForm和MVC两种主要框架,实现方式有所不同。 结合引用和用户需求,以下是一些建议: ### 1. 图表库选择 - **AnyChart**(引用[1]):轻量级,功能丰富,支持SVG/VML,适合Web开发。它支持多种图表类型,并且被列为最佳JavaScript图表库之一。它能够处理大量数据吗?AnyChart有专门的大数据模式,可以处理多达百万个数据点,但实际性能取决于浏览器和硬件。 - **HighCharts**(引用[3]):在引用[3]中提到了在ASP.NET WebForm中使用HighCharts。HighCharts是一个流行的商业图表库(免费用于非商业用途),支持大量数据(通过启用boost模块可以处理数十万甚至百万个数据点)。它支持多种图表类型,并且有良好的文档。 - 其他考虑:还有一些其他图表库如D3.js(高度灵活,但学习曲线陡峭)、Chart.js(轻量,适合简单图表,但处理大量数据可能不是强项)、ECharts(百度开源,处理大量数据能力强)等。 考虑到用户是在ASP.NET环境中,并且需要处理大量数据,推荐使用: - **HighCharts**:因为它有专门的大数据优化(boost模块),并且在引用[3]中有在ASP.NET WebForm中使用的示例。 - **AnyChart**:同样支持大数据,但需要测试其性能。 - **ECharts**:也是一个很好的选择,特别适合大数据量的可视化。 ### 2. 数据格式 - 大多数图表库都支持JSON格式(引用[4]提到JSON是标准格式)。因此,在服务器端(ASP.NET)将数据序列化为JSON传递给前端图表库是最常见的做法。 - 如果数据源是XML,需要确认图表库是否支持(引用[4]提到这一点)。HighCharts和AnyChart都支持XML数据,但通常我们更倾向于使用JSON,因为更轻量。 ### 3. 实现方法 在ASP.NET中,无论是WebForm还是MVC,核心步骤类似: - 从数据库(或其他数据源)获取大量数据。 - 在服务器端对数据进行聚合或处理(减少传输到前端的数据量,因为传输大量数据可能影响性能)。 - 将处理后的数据序列化为JSON(或XML)格式。 - 在前端页面中引入图表库的JS文件,并通过AJAX获取数据,然后渲染图表。 #### 针对大量数据的优化策略: - **数据聚合**:在服务器端对数据进行汇总(例如,按时间间隔聚合,取平均值、最大值等),只传输聚合后的数据到前端。 - **分页加载/懒加载**:如果图表支持,可以只加载当前视图的数据,当用户滚动或缩放时再加载其他部分。 - **使用图表库的大数据模式**:如HighCharts的boost模块,它使用WebGL进行渲染,可以处理大量数据点。 - **服务器端渲染**:对于非常大的数据,可以考虑在服务器端生成图表图片(如使用Bitmap),但这样会失去交互性。折中方案是使用矢量格式(SVG)在服务器端生成,但需要权衡服务器负载。 #### 具体实现步骤(以HighCharts在ASP.NET WebForm为例,参考引用[3]): 1. 在页面中引入HighCharts的JavaScript文件。 2. 在服务器端(C#)从数据库查询数据(例如,使用ADO.NET或Entity Framework)。 3. 将数据转换为适合HighCharts的格式(如数组或对象列表)。 4. 将数据序列化为JSON字符串,并传递给前端(可以通过隐藏字段、页面变量或AJAX获取)。 5. 在前端JavaScript中初始化HighCharts图表,并将数据设置到图表配置中。 示例代码(简化版): **服务器端(C#)**: ```csharp // 假设从数据库获取数据 public class SaleData { public string Category { get; set; } public decimal Amount { get; set; } } protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { // 获取数据(实际中可能从数据库来) List<SaleData> data = GetSaleData(); // 序列化为JSON string jsonData = new JavaScriptSerializer().Serialize(data); // 传递给前端 ScriptManager.RegisterStartupScript(this, GetType(), "data", $"var saleData = {jsonData};", true); } } ``` **前端(HTML/JavaScript)**: ```html <div id="chartContainer" style="width:100%; height:400px;"></div> <script src="https://code.highcharts.com/highcharts.js"></script> <script src="https://code.highcharts.com/modules/boost.js"></script> <!-- 大数据模块 --> <script> // 使用服务器传递的saleData Highcharts.chart('chartContainer', { chart: { type: 'column' }, title: { text: 'Sales by Category' }, series: [{ name: 'Sales', data: saleData.map(item => [item.Category, item.Amount]) }], boost: { enabled: true // 启用boost模块处理大数据 } }); </script> ``` ### 4. 其他注意事项 - **性能**:大量数据在前端渲染可能会造成浏览器卡顿。因此,务必在服务器端进行数据聚合,尽量减少传输到前端的数据点数量。例如,如果有一百万条记录,可以按小时或天聚合,减少到几千个点。 - **图表类型**:某些图表类型(如散点图、折线图)在数据量大时性能要求高,而柱状图、饼图等通常数据量较小。 - **交互性**:如果用户需要与大量数据交互(如缩放、平移),则必须使用支持这些功能的图表库(如HighCharts、ECharts)。 ### 推荐方案 1. **图表库**:HighCharts(商业应用需购买许可证)或ECharts(免费开源)作为首选,因为它们在大数据处理方面表现良好。 2. **数据传输**:使用JSON格式,通过AJAX异步加载数据。 3. **服务器端**:使用ASP.NET Web API或MVC控制器提供数据接口,返回JSON数据。 4. **数据聚合**:在服务器端进行,使用SQL聚合函数或LINQ操作。 ### 相关问题 根据用户的问题,我们可以生成以下相关问题: 1. 在ASP.NET中如何优化大量数据的传输以减少前端加载时间? 2. HighCharts和ECharts在处理百万级数据点时性能对比如何? 3. 如何在ASP.NET WebForm中使用Web API提供图表数据? 4. 有哪些服务器端数据聚合策略可以用于图表展示? 现在,我们将按照要求组织回答。</think>### ASP.NET 处理展示大量数据的图表解决方案 针对ASP.NET环境下处理大规模数据(如百万级记录)的图表展示需求,结合性能、可扩展性和开发效率,提供以下分层解决方案: --- #### 一、核心架构设计(关键优化点) 1. **数据分层处理** - **服务端聚合**:在数据库层预先聚合数据,避免传输原始记录 ```sql -- 示例:按日期聚合销售数据 SELECT CONVERT(date, OrderDate) AS Day, SUM(Amount) FROM Sales GROUP BY CONVERT(date, OrderDate) ``` - **分页加载**:仅传输当前视图所需数据段 ```csharp // C# 分页查询 var pagedData = dbContext.Sales .OrderBy(s => s.Date) .Skip(pageIndex * pageSize) .Take(pageSize) .ToList(); ``` 2. **数据传输优化** - 优先使用**JSON格式**(引用[4]) - 压缩数据体积:移除冗余字段,使用数值替代字符串枚举 - 启用Gzip压缩(IIS配置) ```xml <!-- Web.config --> <httpCompression directory="%SystemDrive%\temp"> <scheme name="gzip" dll="%Windir%\system32\inetsrv\gzip.dll"/> </httpCompression> ``` --- #### 二、推荐图表库及集成方案 | 图表库 | 适用场景 | ASP.NET集成方式 | 大数据支持特性 | |--------------|--------------------------|------------------------------------------|------------------------------| | **ECharts** | 复杂交互图表 | Web API返回JSON + AJAX加载 | 增量渲染、数据采样[^1] | | **Highcharts** | 商业报表 | WebForm用`Literal`控件输出JSON[^3] | Boost模块(WebGL加速) | | **AnyChart** | 快速开发标准图表 | 直接绑定DataTable | 异步数据加载[^1] | | **D3.js** | 高度定制可视化 | MVC Razor视图 + Web API | 虚拟DOM渲染 | > **性能对比公式**: > 渲染效率 $E = \frac{\text{数据点数量}}{\text{渲染时间(ms)}} \times \text{GPU加速因子}$ > 当 $E > 10^4$ 时(即1万点/秒)可满足大多数场景 --- #### 三、分框架实现示例 ##### 1. ASP.NET WebForms + Highcharts ```csharp // 后台代码 (SalesChart.aspx.cs) protected void Page_Load(object sender, EventArgs e) { var data = db.GetSalesSummary(); // 聚合数据查询 string jsonData = JsonConvert.SerializeObject(data); // 注入JS变量 ClientScript.RegisterStartupScript(GetType(), "chartData", $"var chartData = {jsonData};", true); } ``` ```html <!-- 前端容器 --> <div id="chartContainer" style="height: 500px;"></div> <script> // Highcharts初始化 Highcharts.chart('chartContainer', { series: [{ type: 'line', data: chartData, boostThreshold: 5000 // 启用WebGL加速 }] }); </script> ``` ##### 2. ASP.NET MVC + ECharts ```csharp // Controller public ActionResult SalesChart() { var data = _repo.GetAggregatedData(); return Json(data, JsonRequestBehavior.AllowGet); } ``` ```javascript // View (Razor) $.get('/SalesChart').done(function(data) { const chart = echarts.init(document.getElementById('chart')); chart.setOption({ dataset: { source: data }, series: [{ type: 'bar' }] }); }); ``` --- #### 四、性能优化策略 1. **数据层面** - 建立**汇总表**,定时预计算指标 - 使用**内存缓存**:`MemoryCache.Default.Add("salesData", data, DateTime.Now.AddHours(1))` - 启用**数据库索引**:覆盖查询字段 2. **渲染层面** - 开启图表库的**硬件加速**选项(如WebGL) - 实施**数据采样**(Data Sampling): $$ \text{采样间隔} = \frac{\text{总时间范围}}{\text{屏幕像素宽度}} $$ - 使用**渐进渲染**(Progressive Rendering) 3. **传输层面** - 采用**Protocol Buffers**替代JSON(减少30%-50%体积) - 实现**WebSocket**实时更新(避免轮询) --- ### 选型建议 | 场景 | 推荐方案 | 理由 | |-----------------------|------------------------------|------------------------------------------| | 企业级报表系统 | Highcharts + SQL Server聚合 | 商业支持完善,集成SSRS方便[^3] | | 实时监控大屏 | ECharts + WebSocket | 流数据处理能力强,动画流畅 | | 内部数据分析工具 | AnyChart + 内存缓存 | 开发快速,轻量级部署[^1] | | 定制化地理可视化 | D3.js + GeoJSON | 灵活应对复杂定制需求 | > **避坑指南**: > - 避免在前端直接处理>10万条原始记录 > - 禁用图表动画当数据点>5000 > - XML数据源需转换JSON(引用[4])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值