我查询数据库以获取数据.它可能有超过1行.我将它们保存到IEnumerable中.

为什么动态?因为我可能会在表格中添加新列,我不想更改我的代码以再次调整它.

然后,我将IEnumerable转换为datatable.我有一个问题是获取动态对象内的属性.有人可以帮帮我吗?

这是我的代码:

DataTable dt;
string query = "SELECT * FROM WORKSHOP WHERE WORKSHOPID = 1";

// Execute Query
var result = Execute(query);

// Convert IEnumerable<dynamic> to DataTable (I Have Problem Here)
dt = CsvConverter.EnumToDataTable(result);

// Convert DataTable To CSV
var csv = CsvConverter.DataTabletoCsv(dt,",true);

// Save File
string fileName = Path.GetTempPath() + Guid.NewGuid().ToString() + ".csv";
File.AppendAllText(fileName,csv);

// Method to Execute Query
public IEnumerable<dynamic> Execute(string commandText)
{
   using (var result = databaseManager.ReadData(commandText,false))
      foreach (IDataRecord record in result)
      {
         yield return new DataRecordDynamicWrapper(record);
      }
}

// Wrapper of Dynamic Record
public class DataRecordDynamicWrapper : DynamicObject
{
    private IDataRecord _dataRecord;
    public DataRecordDynamicWrapper(IDataRecord dataRecord) { _dataRecord = dataRecord; }

    public override bool TryGetMember(GetMemberBinder binder,out object result)
    {
        result = _dataRecord[binder.Name];
        return result != null;
    }
}

// Method to Convert Enum to DT
public static DataTable EnumToDataTable<T>(IEnumerable<T> l_oItems)
    {
        DataTable oReturn = new DataTable(typeof (T).Name);
        object[] a_ovalues;
        int i;

        //#### Collect the a_oProperties for the passed T
        PropertyInfo[] a_oProperties = typeof (T).GetType().GetProperties();


        //#### Traverse each oProperty,.Add'ing each .Name/.BaseType into our oReturn value
        //####     NOTE: The call to .BaseType is required as DataTables/DataSets do not support nullable types,so it's non-nullable counterpart Type is required in the .Column deFinition
        foreach (PropertyInfo oProperty in a_oProperties)
        {
            oReturn.Columns.Add(oProperty.Name,BaseType(oProperty.PropertyType));
        }

        //#### Traverse the l_oItems
        foreach (T oItem in l_oItems)
        {
            //#### Collect the a_ovalues for this loop
            a_ovalues = new object[a_oProperties.Length];

            //#### Traverse the a_oProperties,populating each a_ovalues as we go
            for (i = 0; i < a_oProperties.Length; i++)
            {
                a_ovalues[i] = a_oProperties[i].GetValue(oItem,null);
            }

            //#### .Add the .Row that represents the current a_ovalues into our oReturn value
            oReturn.Rows.Add(a_ovalues);
        }

        //#### Return the above determined oReturn value to the caller
        return oReturn;
    }

    public static Type BaseType(Type oType)
    {
        //#### If the passed oType is valid,.IsValueType and is logicially nullable,.Get(its)UnderlyingType
        if (oType != null && oType.IsValueType &&
            oType.IsGenericType && oType.GetGenericTypeDeFinition() == typeof (Nullable<>)
            )
        {
            return Nullable.GetUnderlyingType(oType);
        }
            //#### Else the passed oType was null or was not logicially nullable,so simply return the passed oType
        else
        {
            return oType;
        }
    }

解决方法

您不能使用反射API枚举DynamicObject的动态绑定成员.您只能按需按名称绑定到它们.您编写的代码将仅返回在实际DynamicObject类上定义的属性,该类不定义任何属性(因此为空数组).

作为使用反射的替代方法,您可以让DataRecordDynamicWrapper实现ICustomTypeDescriptor,这样您就可以在数据记录中公开属性(complete example here):

public class DataRecordDynamicWrapper : DynamicObject,ICustomTypeDescriptor
{
    private IDataRecord _dataRecord;
    private PropertyDescriptorCollection _properties;

    //
    // (existing members)
    //

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties()
    {
        if (_properties == null)
            _properties = GenerateProperties();
        return _properties;
    }

    private PropertyDescriptorCollection GenerateProperties()
    {
        var count = _dataRecord.FieldCount;
        var properties = new PropertyDescriptor[count];

        for (var i = 0; i < count; i++)
        {
            properties[i] = new DataRecordProperty(
                i,_dataRecord.GetName(i),_dataRecord.GetFieldType(i));
        }

        return new PropertyDescriptorCollection(properties);
    }

    //
    // (implement other ICustomTypeDescriptor members...)
    //

    private sealed class DataRecordProperty : PropertyDescriptor
    {
        private static readonly Attribute[] NoAttributes = new Attribute[0];

        private readonly int _ordinal;
        private readonly Type _type;

        public DataRecordProperty(int ordinal,string name,Type type)
            : base(name,NoAttributes)
        {
            _ordinal = ordinal;
            _type = type;
        }

        public override bool CanResetValue(object component)
        {
            return false;
        }

        public override object GetValue(object component)
        {
            var wrapper = ((DataRecordDynamicWrapper)component);
            return wrapper._dataRecord.GetValue(_ordinal);
        }

        public override void ResetValue(object component)
        {
            throw new NotSupportedException();
        }

        public override void SetValue(object component,object value)
        {
            throw new NotSupportedException();
        }

        public override bool ShouldSerializeValue(object component)
        {
            return true;
        }

        public override Type ComponentType
        {
            get { return typeof(IDataRecord); }
        }

        public override bool IsReadOnly
        {
            get { return true; }
        }

        public override Type PropertyType
        {
            get { return _type; }
        }
    }
}

然后,您可以修改EnumToDataTable()方法以使用System.ComponenetModel API而不是System.Reflection:

public static DataTable EnumToDataTable<T>(IEnumerable<T> l_oItems)
{
    var firstItem = l_oItems.FirstOrDefault();
    if (firstItem == null)
        return new DataTable();

    DataTable oReturn = new DataTable(TypeDescriptor.GetClassName(firstItem));
    object[] a_ovalues;
    int i;

    var properties = TypeDescriptor.GetProperties(firstItem);

    foreach (PropertyDescriptor property in properties)
    {
        oReturn.Columns.Add(property.Name,BaseType(property.PropertyType));
    }

    //#### Traverse the l_oItems
    foreach (T oItem in l_oItems)
    {
        //#### Collect the a_ovalues for this loop
        a_ovalues = new object[properties.Count];

        //#### Traverse the a_oProperties,populating each a_ovalues as we go
        for (i = 0; i < properties.Count; i++)
            a_ovalues[i] = properties[i].GetValue(oItem);

        //#### .Add the .Row that represents the current a_ovalues into our oReturn value
        oReturn.Rows.Add(a_ovalues);
    }

    //#### Return the above determined oReturn value to the caller
    return oReturn;
}

这种方法的好处是EnumToDataTable()将回退到没有实现ICustomTypeDescriptor的项的标准类型描述符(例如,对于普通的旧CLR对象,它将表现得与原始代码类似).

c# – 将IEnumerable转换为DataTable的更多相关文章

  1. 在swift中获取NSImage的PNG表示

    非常感谢文件说:所以它期望一本字典,而不是一个零值.提供像这样的空字典:只有在指定了Optional(即[NSObject:AnyObject]的位置?)时才能传递nil值.

  2. android – Eclipse:覆盖project.properties中定义的库路径

    我正在使用ActionBarSherlock作为库.我们没有将ABS包含在我们的存储库中,因此参与ourproject的每个人都必须单独下载并安装它.ActioBarSherlock是一个Android库项目,我通过在同一个Eclipse的工作区中打开它和我的项目来运行它(它们都没有复制到工作区,它们都存在于另一个文件夹中)并通过以下方式将它添加到我的project.properties中:Ref

  3. android – Crashlytics无法使用fabric.properties找到清单

    我正在使用classpath’io.fabric.tools:gradle:1.‘并且在我用于fabric插件的模块中有一个fabric.properties.当我运行gradlewcrashlyticsuploaddistributionProdStaging时,我得到:为什么?解决方法在我使用正确的数据更新fabric.properties并拆分命令后,它工作正常:没有它,错误仍然出现.

  4. 缺少android.compileSdkVersion!错误gradle build

    我正在尝试构建我的库并将其上传到存储库,但不幸的是gradle构建失败.我花了几个小时试图修复这个错误,但我尝试的没有任何帮助.这是我从根项目目录的build.gradle.和我的模块目录中的build.gradle我还在local.properties文件中添加了一些配置问题是我在gradlebintrayUpload之后遇到以下错误.在错误消息输出结束时,我得到了以下内容解决方法与“编译sdk

  5. android – Gitignore没有忽略某些project.properties

    我正在使用Windows和Mac的github应用程序,我的.gitignore文件有问题.我试图忽略在我的两台机器之间切换时生成的project.properties文件,但我似乎无法让它工作.下面是我的.gitignore的副本,它似乎适用于除了project.properties之外的所有东西,以及我在那里的gen/*,但不那么烦人.我一直在研究这个问题并且没有找到答案,我将不胜感激任何帮助!

  6. ajax读取properties资源文件数据的方法

    这篇文章主要介绍了ajax读取properties资源文件数据的方法,实例分析了基于Ajax实现读取properties资源文件数据的相关技巧,需要的朋友可以参考下

  7. SpringBoot读取自定义配置文件方式(properties,yaml)

    这篇文章主要介绍了SpringBoot读取自定义配置文件方式(properties,yaml),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  8. Properties 持久的属性集的实例详解

    这篇文章主要介绍了Properties 持久的属性集的实例详解的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下

  9. gradle中的properties文件详解

    这篇文章主要介绍了gradle中的properties文件详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  10. JSP 中Spring的Resource类读写中文Properties实例代码

    这篇文章主要介绍了JSP 中Spring的Resource类读写中文Properties实例代码的相关资料,需要的朋友可以参考下

随机推荐

  1. c# – (wpf)Application.Current.Resources vs FindResource

    所以,我正在使用C#中的WPF创建一个GUI.它看起来像这样:它现在还没有完成.这两行是我尝试制作一种数据表,它们在XAML中是硬编码的.现在,我正在C#中实现添加新的水果按钮功能.我在XAML中有以下样式来控制行的背景图像应该是什么样子:因此,在代码中,我为每列col0,col1和col2创建一个图像,如果我使用以下代码,它添加了一个如下所示的新行:如你所见,它不太正确……为什么一个似乎忽略了一些属性而另一个没有?

  2. c# – 绑定DataGridTemplateColumn

    似乎我已经打了个墙,试图在DataGrid上使用DataTemplates.我想要做的是使用一个模板来显示每个单元格的两行文本.但是似乎无法以任何方式绑定列.以下代码希望显示我想做的事情.注意每个列的绑定:模板列没有这样的东西,因此,这个xaml不可能工作.我注定要将整个DataTemplate复制到每个列,只是对每个副本都有不同的约束?解决方法我不完全确定你想要做什么,但如果您需要获取整行的DataContext,可以使用RelativeSource绑定来移动视觉树.像这样:

  3. c# – 学习设计模式的资源

    最近我来到了这个设计模式的概念,并对此感到非常热情.你能建议一些帮助我深入设计模式的资源吗?

  4. c# – 是否有支持嵌入HTML页面的跨操作系统GUI框架?

    我想开发一个桌面应用程序来使用跨系统,是否有一个GUI框架,允许我为所有3个平台编写一次代码,并具有完全可脚本化的嵌入式Web组件?我需要它有一个API来在应用程序和网页之间进行交流.我知道C#,JavaScript和一些python.解决方法Qt有这样的事情QWebView.

  5. c# – 通过字符串在对象图中查找属性

    我试图使用任意字符串访问嵌套类结构的各个部分.给出以下(设计的)类:我想要从Person对象的一个实例的“PersonsAddress.HousePhone.Number”获取对象.目前我正在使用反思来做一些简单的递归查找,但是我希望有一些忍者有更好的想法.作为参考,这里是我开发的(crappy)方法:解决方法您可以简单地使用标准的.NETDataBinder.EvalMethod,像这样:

  6. c# – 文件下载后更新页面

    FamilyID=0a391abd-25c1-4fc0-919f-b21f31ab88b7&displaylang=en&pf=true它呈现该页面,然后使用以下元刷新标签来实际向用户提供要下载的文件:你可能需要在你的应用程序中做类似的事情.但是,如果您真的有兴趣在文件完全下载后执行某些操作,那么您的运气不佳,因为没有任何事件可以与浏览器进行通信.执行此操作的唯一方法是上传附件时使用的AJAXupload.

  7. c# – 如何在每个机器应用程序中实现单个实例?

    我必须限制我的.net4WPF应用程序,以便每台机器只能运行一次.请注意,我说每个机器,而不是每个会话.我使用一个简单的互斥体实现单实例应用程序,直到现在,但不幸的是,这样一个互斥是每个会话.有没有办法创建机器互连,还是有其他解决方案来实现每个机器应用程序的单个实例?

  8. c# – WCF和多个主机头

    我的雇主网站有多个主机名,都是同一个服务器,我们只是显示不同的皮肤来进行品牌宣传.不幸的是,在这种情况下,WCF似乎不能很好地工作.我试过overridingthedefaulthostwithacustomhostfactory.这不是一个可以接受的解决方案,因为它需要从所有主机工作,而不仅仅是1.我也看过thisblogpost,但是我无法让它工作,或者不是为了解决我的问题.我得到的错误是“这

  9. c# – ASP.NET MVC模型绑定与表单元素名称中的虚线

    我一直在搜索互联网,试图找到一种方式来容纳我的表单元素的破折号到ASP.NET的控制器在MVC2,3或甚至4中的默认模型绑定行为.作为一名前端开发人员,我更喜欢在我的CSS中使用camelCase或下划线进行破折号.在我的标记中,我想要做的是这样的:在控制器中,我会传入一个C#对象,看起来像这样:有没有办法通过一些正则表达式或其他行为来扩展Controller类来适应这种情况?我讨厌这样的事实,我必须这样做:甚至这个:思考?

  10. c# – 用户界面设计工具

    我正在寻找一个用户界面设计工具来显示文档中可能的GUI.我不能生成代码.我知道MicrosoftVisio提供了一个功能.但有什么办法吗?您使用哪种软件可视化GUI?

返回
顶部