将DataTable 转成 List<dynamic>,主要用于给dapper批量操作时传参数。

在维护一个老项目过程中,为了愉快的使用 dapper 从datatable中获取要批量操作的数据而不用再手动写一堆匿名对象集合,所以写了个下面的静态方法,用来支持dapper的写数据库方法。记录一下以免以后做重复工作。直接上代码:

/// <summary>
/// 将DataTable 转成 List<dynamic>,主要用于给dapper批量操作时传参数。
/// </summary>
/// <param name="table">要转换的DataTable对象</param>
/// <param name="filterFields">要筛选的列。默认不传,此时返回全部列</param>
/// <param name="includeOrExclude">指定上一个参数条件是要保留的列还是要排除的列</param>
/// <returns></returns>
public static List<dynamic> ToDynamicList(this DataTable table, string[] filterFields = null, bool includeOrExclude = true)
{
    var modelList = new List<dynamic>();
    var isFilter = filterFields != null && filterFields.Any();
    IEnumerable reservedColumns = table.Columns;
    if (isFilter)
        reservedColumns = table.Columns.Cast<DataColumn>().Where(c => filterFields.Contains(c.ColumnName) == includeOrExclude);
    foreach (DataRow row in table.Rows)
    {
        dynamic model = new ExpandoObject();
        var dict = (IDictionary<string, object>)model;
        foreach (DataColumn column in reservedColumns)
        {
            dict[column.ColumnName] = row[column];
        }
        modelList.Add(model);
    }
    return modelList;
}

然后,在操作Dapper 批量的增、删除、改 数据库表中的数据时,就可以这样从dataTable获取数据:

bool commitOK = false;
using (IDbConnection con = new System.Data.SqlClient.SqlConnection(constr))
{
    if (con.State == ConnectionState.Closed)
        con.Open();
    IDbTransaction transaction = con.BeginTransaction();

    var strInsert = $"insert into PriceStrategy(item_clsno, model, color, jhPrice, pfPrice) values(@item_clsno, @model, @color, @jhPrice, @pfPrice)";
    var strUpdate = $"update PriceStrategyset model=@model, color=@color, jhPrice=@jhPrice, pfPrice=@pfPrice,updatedTime=getdate() where id=@id";
    var strDelete = $"delete PriceStrategywhere id=@id";

    if (dataTable.GetChanges(DataRowState.Added)?.Rows?.Count > 0)
        await con.ExecuteAsync(strInsert, dataTable.GetChanges(DataRowState.Added).ToDynamicList(new [] { "item_clsno", "model", "color", "jhPrice", "pfPrice" }), transaction);
    if (dataTable.GetChanges(DataRowState.Modified)?.Rows?.Count > 0)
        await con.ExecuteAsync(strUpdate, dataTable.GetChanges(DataRowState.Modified).ToDynamicList(new [] { "id", "model", "color", "jhPrice", "pfPrice" }), transaction);
    if (dataTable.GetChanges(DataRowState.Deleted)?.Rows?.Count > 0)
        await con.ExecuteAsync(strDelete, dataTable.GetChanges(DataRowState.Deleted).ToDynamicList(new [] { "id" }), transaction);
    try
    {
        transaction.Commit();
        commitOK = true;
    }
    catch
    {
        transaction.Rollback();
        throw;
    }
}
if (commitOK)
{
    MessageBox.Show(this, "保存成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}

上面代码中的三个调用都使用了静态方法的列筛选,如果你的项目是小数据量、不太多的列则上面的方法在不考虑性能的情况下完全可以粗暴的改为直接.ToDynamicList() 即把整个datatable的所有列都转成List<dynamic>集合,完全没有问题。

这样操作比 Ado.Net 时代确实跨进了一步。当然现代开发都流行使用 EntityFrameworkCore 等功能更强大的ORM工具。如果你像我一样是在维护一些老项目,希望本篇博文对你有帮助,别忘记点个赞。

要将一个DaTaTable换为List<T>,可以使用以下步骤: 1. 创建一个类来表示DaTaTable中的每一行据。这个类应该包含与DaTaTable中的列对应的属性。 2. 创建一个List<T>对象,其中T是第一步中创建的类。 3. 使用foreach循环遍历DaTaTable中的每一行据。 4. 在循环中,创建T类型的对象,并将DaTaTable中的每一列的值赋值给T对象的相应属性。 5. 将T对象添加到List<T>中。 6. 返回List<T>对象。 以下是一个示例代码: ``` public class MyDataClass { public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } } public List<MyDataClass> ConvertDataTableToList(DataTable dt) { List<MyDataClass> list = new List<MyDataClass>(); foreach (DataRow row in dt.Rows) { MyDataClass obj = new MyDataClass(); obj.Id = Convert.ToInt32(row["Id"]); obj.Name = row["Name"].ToString(); obj.Description = row["Description"].ToString(); list.Add(obj); } return list; } ``` 在这个示例中,我们创建了一个名为MyDataClass的类来表示DaTaTable中的每一行据。我们还创建了一个名为ConvertDataTableToList的方法,该方法接受一个DataTable对象作为参,并将其换为List<MyDataClass>对象。在方法中,我们使用foreach循环遍历DaTaTable中的每一行据,并为每一行据创建一个MyDataClass对象。然后,我们将DaTaTable中的每一列的值赋值给MyDataClass对象的相应属性,并将MyDataClass对象添加到List<MyDataClass>中。最后,我们返回List<MyDataClass>对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值