• DynamicDataSet


    通常我们都是像下面这样使用一个DataSet或者DataTable:
    DataSet dataSet = PrepareDataSet();
    var userCount = (int)dataSet.Tables["Users"].Rows.Count;
    var userName = dataSet.Tables["Users"].Rows[0]["Name"] as string;
    var userAge = (int)dataSet.Tables["Users"].Rows[0]["Age"];
    那么我们有没有办法像下面这样使用DataSet或者DataTable呢?
    var userCount = dynamicDataSet.Users.Count;
    var userName = dynamicDataSet.Users.Name[0];
    var userAge = dynamicDataSet.Users.Age[0];
    利用.NET4.0中新的DLR可以很容易的就实现这个功能,代码如下:
        class Program
    {
    static void Main(string[] args)
    {
    dynamic dynamicDataSet = new DynamicDataSet(PrepareDataSet());
    var userCount = dynamicDataSet.Users.Count;
    var userName = dynamicDataSet.Users.Name[0];
    var userAge = dynamicDataSet.Users.Age[0];
    }

    public static DataSet PrepareDataSet()
    {
    DataTable dataTable = new DataTable("Users");
    dataTable.Columns.Add("Name", typeof(string));
    dataTable.Columns.Add("Age", typeof(int));
    DataRow dataRow = dataTable.NewRow();
    dataRow[0] = "Davis";
    dataRow[1] = "31";
    dataTable.Rows.Add(dataRow);
    DataSet dataSet = new DataSet();
    dataSet.Tables.Add(dataTable);
    return dataSet;
    }
    }
    using System;
    using System.Data;
    using System.Dynamic;

    namespace Zxf.ExpressionBuilder
    {
    public class DynamicDataSet : DynamicObject
    {
    private readonly Object m_Data;
    private readonly string m_Field;

    public DynamicDataSet(DataSet obj)
    {
    m_Data = obj;
    }

    public DynamicDataSet(DataTable obj)
    {
    m_Data = obj;
    }

    public DynamicDataSet(DataRowCollection obj, string field)
    {
    m_Data = obj;
    m_Field = field;
    }

    public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
    {
    if (m_Data is DataRowCollection)
    {
    var dtRows = m_Data as DataRowCollection;
    if (binder.CallInfo.ArgumentCount == 1 && indexes[0] is int)
    {
    result = dtRows[Convert.ToInt32(indexes[0].ToString())][m_Field];
    if (result is string)
    {
    result = result.ToString().Trim();
    }
    return true;
    }
    }

    result = null;
    return false;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
    if (m_Data is DataSet)
    {
    var ds = m_Data as DataSet;
    if (ds.Tables.Contains(binder.Name))
    {
    result = new DynamicDataSet(ds.Tables[binder.Name]);
    return true;
    }
    result = null;
    return false;
    }

    if (m_Data is DataTable)
    {
    var dt = m_Data as DataTable;
    if (dt.Columns.Contains(binder.Name))
    {
    result = new DynamicDataSet(dt.Rows, binder.Name);
    return true;
    }
    if (binder.Name.ToUpper() == "COUNT")
    {
    result = dt.Rows.Count;
    return true;
    }
    result = null;
    return false;
    }

    if (m_Data is DataRowCollection && binder.Name.ToUpper() == "SUM")
    {
    var dataRows = m_Data as DataRowCollection;
    dynamic sumResult = 0;
    foreach (DataRow row in dataRows)
    {
    if (row[m_Field] is decimal)
    {
    sumResult = (decimal)sumResult + (dynamic)row[m_Field];
    }
    else
    {
    sumResult += (dynamic)row[m_Field];
    }

    }
    result = sumResult;
    return true;
    }

    result = null;
    return false;
    }
    }
    }
    也可以利用Expression.Dynamic来实现动态执行之前的dynamicDataSet.Users.Count语句:
        using System;
    using System.Data;
    using System.Linq.Expressions;
    using System.Runtime.CompilerServices;
    using Microsoft.CSharp.RuntimeBinder;
    using Zxf.ExpressionBuilder;

    class Program
    {
    static void Main(string[] args)
    {
    ParameterExpression expressionParameter = DynamicExpression.Parameter(typeof(DynamicDataSet));

    CallSiteBinder binderGetUsers = Microsoft.CSharp.RuntimeBinder.Binder.GetMember(CSharpBinderFlags.None, "Users", typeof(Object)
    , new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
    DynamicExpression getUsersExpression = Expression.Dynamic(binderGetUsers, typeof(object), expressionParameter);

    CallSiteBinder binderGetCount = Microsoft.CSharp.RuntimeBinder.Binder.GetMember(CSharpBinderFlags.None, "Count", typeof(Object)
    , new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
    DynamicExpression getCountExpression = Expression.Dynamic(binderGetCount, typeof(object), getUsersExpression);

    Expression<Func<DynamicDataSet, object>> dynamicLambdaExp = Expression.Lambda<Func<DynamicDataSet, object>>(getCountExpression
    , new ParameterExpression[] { expressionParameter });
    Func<DynamicDataSet, object> dynamicLambdaExpFunc = dynamicLambdaExp.Compile();

    dynamic dynamicDataSet = new DynamicDataSet(PrepareDataSet());
    int? count = dynamicLambdaExpFunc.Invoke(dynamicDataSet) as int?;
    }

    public static DataSet PrepareDataSet()
    {
    DataTable dataTable = new DataTable("Users");
    dataTable.Columns.Add("Name", typeof(string));
    dataTable.Columns.Add("Age", typeof(int));
    DataRow dataRow = dataTable.NewRow();
    dataRow[0] = "Davis";
    dataRow[1] = "31";
    dataTable.Rows.Add(dataRow);
    DataSet dataSet = new DataSet();
    dataSet.Tables.Add(dataTable);
    return dataSet;
    }
    }
    
    

     
  • 相关阅读:
    白话SSL协议的握手过程
    PHP进程高负载
    Apache不定时宕机
    KindEditor
    过滤进程命令
    LAMP 平台必建安装包
    scp command
    ssl_request_log日志拆分
    Day01:Python入门
    Day03:集合、文件处理和函数基础
  • 原文地址:https://www.cnblogs.com/zanxiaofeng/p/1765168.html
Copyright © 2020-2023  润新知