增加IEnumerable<>扩展方法,实现枚举类型到DataTable的转换
This commit is contained in:
parent
9ab32a2d4d
commit
2e1a0ad0c0
89
Falcon.SugarApi.Test/IEnumerableExtendTest.cs
Normal file
89
Falcon.SugarApi.Test/IEnumerableExtendTest.cs
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi.Test
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 枚举类型扩展方法
|
||||||
|
/// </summary>
|
||||||
|
[TestClass]
|
||||||
|
public class IEnumerableExtendTest
|
||||||
|
{
|
||||||
|
[TestMethod("ToDataTable测试")]
|
||||||
|
public void ToDataTableTest() {
|
||||||
|
var sw = new Stopwatch();
|
||||||
|
var list = new List<dynamic> {
|
||||||
|
new{a=1,b="b1" },
|
||||||
|
new{a=2,b="b2",c=1 },
|
||||||
|
};
|
||||||
|
sw.Start();
|
||||||
|
var r = list.ToDataTable();
|
||||||
|
sw.Stop();
|
||||||
|
Console.WriteLine($"ToDataTable转换,共用时{sw.ElapsedMilliseconds}毫秒");
|
||||||
|
//测试表
|
||||||
|
Assert.IsNotNull(r);
|
||||||
|
Assert.AreEqual(3, r.Columns.Count);
|
||||||
|
Assert.AreEqual(2, r.Rows.Count);
|
||||||
|
//测试列
|
||||||
|
var col1 = r.Columns[0];
|
||||||
|
Assert.IsTrue(col1.ColumnName == "a");
|
||||||
|
Assert.IsTrue(col1.DataType == typeof(int));
|
||||||
|
var col2 = r.Columns[1];
|
||||||
|
Assert.IsTrue(col2.ColumnName == "b");
|
||||||
|
Assert.IsTrue(col2.DataType == typeof(string));
|
||||||
|
var col3 = r.Columns[2];
|
||||||
|
Assert.IsTrue(col3.ColumnName == "c");
|
||||||
|
Assert.IsTrue(col3.DataType == typeof(int));
|
||||||
|
//测试行
|
||||||
|
var row = r.Rows[0];
|
||||||
|
Assert.IsTrue(row[0].ToString() == "1");
|
||||||
|
Assert.IsTrue(row[1].ToString() == "b1");
|
||||||
|
Assert.IsTrue(row[2].ToString() == "");
|
||||||
|
row = r.Rows[1];
|
||||||
|
Assert.IsTrue((int)row[0] == 2);
|
||||||
|
Assert.IsTrue((string)row[1] == "b2");
|
||||||
|
Assert.IsTrue((int)row[2] == 1);
|
||||||
|
Console.WriteLine($"ToDataTable测试完成");
|
||||||
|
|
||||||
|
var models = new List<ToDataTableTestModel> {
|
||||||
|
new ToDataTableTestModel{ id=1, },
|
||||||
|
new ToDataTableTestModel{id=2,Name="name2" },
|
||||||
|
};
|
||||||
|
sw.Reset();
|
||||||
|
r = models.ToDataTable();
|
||||||
|
sw.Stop();
|
||||||
|
Console.WriteLine($"ToDataTable<>转换,共用时{sw.ElapsedMilliseconds}毫秒");
|
||||||
|
//测试表
|
||||||
|
Assert.IsNotNull(r);
|
||||||
|
Assert.AreEqual(2, r.Columns.Count);
|
||||||
|
Assert.AreEqual(2, r.Rows.Count);
|
||||||
|
//测试列
|
||||||
|
col1 = r.Columns[0];
|
||||||
|
Assert.IsTrue(col1.ColumnName == "id");
|
||||||
|
Assert.IsTrue(col1.DataType == typeof(int));
|
||||||
|
col2 = r.Columns[1];
|
||||||
|
Assert.IsTrue(col2.ColumnName == "Name");
|
||||||
|
Assert.IsTrue(col2.DataType == typeof(string));
|
||||||
|
//测试行
|
||||||
|
row = r.Rows[0];
|
||||||
|
Assert.IsTrue(row[0].ToString() == "1");
|
||||||
|
Assert.IsTrue(row[1].ToString() == "");
|
||||||
|
row = r.Rows[1];
|
||||||
|
Assert.IsTrue((int)row[0] == 2);
|
||||||
|
Assert.IsTrue(row[1].ToString() == "name2");
|
||||||
|
Console.WriteLine($"ToDataTable<>测试完成");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ToDataTableTestModel
|
||||||
|
{
|
||||||
|
public int id { get; set; }
|
||||||
|
public string Name { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
88
Falcon.SugarApi/IEnumerableExtend.cs
Normal file
88
Falcon.SugarApi/IEnumerableExtend.cs
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Data;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Falcon.SugarApi
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 枚举扩展
|
||||||
|
/// </summary>
|
||||||
|
public static class IEnumerableExtend
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 枚举转换为DataTable
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="source">数据枚举</param>
|
||||||
|
/// <returns>转换后Datatable</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">参数为Null</exception>
|
||||||
|
public static DataTable ToDataTable(this IEnumerable<object> source) {
|
||||||
|
_ = source ?? throw new ArgumentNullException(nameof(source));
|
||||||
|
var dt = new DataTable();
|
||||||
|
if (source.Count() == 0) {
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < source.Count(); i++) {
|
||||||
|
var item = source.ToArray()[i];
|
||||||
|
foreach (PropertyInfo pro in item.GetType().GetProperties()) {
|
||||||
|
if (!dt.Columns.Contains(pro.Name)) {
|
||||||
|
dt.Columns.Add(new DataColumn {
|
||||||
|
ColumnName = pro.Name,
|
||||||
|
DataType = pro.PropertyType,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var i in source) {
|
||||||
|
var row = dt.NewRow();
|
||||||
|
foreach (var p in i.GetType().GetProperties()) {
|
||||||
|
if (p.CanRead) {
|
||||||
|
var val = p.GetValue(i);
|
||||||
|
try {
|
||||||
|
row[p.Name] = val;
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
throw new Exception($"值设置失败!{p.Name}:{val}", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dt.Rows.Add(row);
|
||||||
|
}
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 枚举转换为DataTable
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">枚举的元素类型</typeparam>
|
||||||
|
/// <param name="source">原数据</param>
|
||||||
|
/// <returns>转换后Datatable</returns>
|
||||||
|
/// <exception cref="ArgumentNullException">参数为Null</exception>
|
||||||
|
public static DataTable ToDataTable<T>(this IEnumerable<T> source) {
|
||||||
|
_ = source ?? throw new ArgumentNullException(nameof(source));
|
||||||
|
var type = typeof(T);
|
||||||
|
var dt = new DataTable();
|
||||||
|
var pros = typeof(T).GetProperties();
|
||||||
|
foreach (PropertyInfo p in pros) {
|
||||||
|
if (p.CanRead) {
|
||||||
|
dt.Columns.Add(new DataColumn {
|
||||||
|
ColumnName = p.Name,
|
||||||
|
DataType = p.PropertyType,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var i in source) {
|
||||||
|
var row = dt.NewRow();
|
||||||
|
foreach (var p in pros) {
|
||||||
|
if (p.CanRead) {
|
||||||
|
var val = p.GetValue(i);
|
||||||
|
row[p.Name] = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dt.Rows.Add(row);
|
||||||
|
}
|
||||||
|
return dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
README.md
24
README.md
|
@ -1,7 +1,7 @@
|
||||||
## Falcon.SugarApi
|
## Falcon.SugarApi
|
||||||
|
|
||||||
### WebApi扩展模块 [进入](/Falcon/Falcon.SugarApi/src/branch/master/Falcon.SugarApi/ApiDefinistions)
|
### WebApi扩展模块 [进入](/Falcon/Falcon.SugarApi/src/branch/master/Falcon.SugarApi/ApiDefinistions)
|
||||||
> `ApiControllerBase`webapi基类,实现数据库、log、异常等基础功能。
|
> `ApiControllerBase`是所有webapi基类,实现数据库、log、异常等基础功能。
|
||||||
> `ApiBaseOptionController<>`带有基本操作方法的webapi基类,除了`ApiControllerBase`功能外还提供基础增删改查功能。
|
> `ApiBaseOptionController<>`带有基本操作方法的webapi基类,除了`ApiControllerBase`功能外还提供基础增删改查功能。
|
||||||
|
|
||||||
### Swagger扩展模块 [进入](/Falcon/Falcon.SugarApi/src/branch/master/Falcon.SugarApi/Swagger)
|
### Swagger扩展模块 [进入](/Falcon/Falcon.SugarApi/src/branch/master/Falcon.SugarApi/Swagger)
|
||||||
|
@ -13,6 +13,17 @@
|
||||||
> `SugarDbTables<T>`数据库表集合基类,可以继承该类并在其中定义`DbSet<T>`属性,这些属性会自动实例化。
|
> `SugarDbTables<T>`数据库表集合基类,可以继承该类并在其中定义`DbSet<T>`属性,这些属性会自动实例化。
|
||||||
> `SugarTableBase`标准表基类,继承该类可提供数据表基础功能,比如ID,创建和修改时间等。
|
> `SugarTableBase`标准表基类,继承该类可提供数据表基础功能,比如ID,创建和修改时间等。
|
||||||
|
|
||||||
|
### 后台任务BackTask模块 [进入](/Falcon/Falcon.SugarApi/src/branch/master/Falcon.SugarApi/BackTask)
|
||||||
|
> 继承`BackgroundLongTask`可以实现一个长期位于后台执行的对象,该类通过`IServiceCollection.AddHostedService<>'进行注册。
|
||||||
|
> `RunTimespan`属性设置执行的时间间隔的秒数。
|
||||||
|
> 重写`RunAsync`方法实现一个异步任务。
|
||||||
|
> 另外可以重写`OnStart`后台任务开始,`OnStop`后台任务结束,`OnCompleted`一次执行完成和`OnException`执行中引发未处理的异常。
|
||||||
|
|
||||||
|
### 数据缓冲模块 [进入](/Falcon/Falcon.SugarApi/src/branch/master/Falcon.SugarApi/Cache)
|
||||||
|
> 通过`IServiceCollection.AddSugarRedisCache` 或 `IServiceCollection.AddSugarMemoryCache`方法注册缓冲器。
|
||||||
|
> 通过注入 `ISugarCache`同步接口 或 `ISugarCacheAsync`异步接口获取组件。
|
||||||
|
> 通过接口的`Get`和`Set`方法获取和保存缓冲值。
|
||||||
|
|
||||||
### XML序列化扩展模块 [进入](/Falcon/Falcon.SugarApi/src/branch/master/Falcon.SugarApi/XmlSerialize)
|
### XML序列化扩展模块 [进入](/Falcon/Falcon.SugarApi/src/branch/master/Falcon.SugarApi/XmlSerialize)
|
||||||
> `IServiceCollection.AddXmlSerializeFactory`方法注册xml序列化工厂`XmlSerializeFactory`,可以通过该工厂实例化一个XML序列化器。
|
> `IServiceCollection.AddXmlSerializeFactory`方法注册xml序列化工厂`XmlSerializeFactory`,可以通过该工厂实例化一个XML序列化器。
|
||||||
|
|
||||||
|
@ -26,13 +37,6 @@
|
||||||
### Object扩展方法
|
### Object扩展方法
|
||||||
> `CloneTo`和`CloneFrom`实现将对象属性赋值到目标对象同名属性中,此为浅表复制。
|
> `CloneTo`和`CloneFrom`实现将对象属性赋值到目标对象同名属性中,此为浅表复制。
|
||||||
|
|
||||||
### 后台任务BackTask模块 [进入](/Falcon/Falcon.SugarApi/src/branch/master/Falcon.SugarApi/BackTask)
|
### IEnumerable扩展方法
|
||||||
> 继承`BackgroundLongTask`可以实现一个长期位于后台执行的对象,该类通过`IServiceCollection.AddHostedService<>'进行注册。
|
> `ToDataTable`和`ToDataTable<>`分别实现将枚举类型转换为DataTable的方法,区别是一个针对Object枚举一个针对具体类型枚举,尽量使用泛型版本,更加高效。
|
||||||
> `RunTimespan`属性设置执行的时间间隔的秒数。
|
|
||||||
> 重写`RunAsync`方法实现一个异步任务。
|
|
||||||
> 另外可以重写`OnStart`后台任务开始,`OnStop`后台任务结束,`OnCompleted`一次执行完成和`OnException`执行中引发未处理的异常。
|
|
||||||
|
|
||||||
### 数据缓冲模块 [进入](/Falcon/Falcon.SugarApi/src/branch/master/Falcon.SugarApi/Cache)
|
|
||||||
> 通过`IServiceCollection.AddSugarRedisCache` 或 `IServiceCollection.AddSugarMemoryCache`方法注册缓冲器。
|
|
||||||
> 通过注入 `ISugarCache`同步接口 或 `ISugarCacheAsync`异步接口获取组件。
|
|
||||||
> 通过接口的`Get`和`Set`方法获取和保存缓冲值。
|
|
Loading…
Reference in New Issue
Block a user