如何将数据表绑定到自定义对象列表

本文关键字:自定义 对象 列表 绑定 数据表 | 更新日期: 2023-09-27 18:03:05

我有一个保存任务的类:

class Task{
  public string Description;
  public DateTime StartDate;
  public DateTime EndDate;
}

我有一个SQLite数据库,有一个名为"任务"的DataTable:

DataTable.Rows[0]["Description"].ToString() // "Draw a cat"
DataTable.Rows[0]["BeginDate"].ToString() // "2016-08-17 9:47:22 AM"
DataTable.Rows[0]["EndDate"].ToString() // "2016-08-17 11:22:37 AM"

我可以创建从DataTable填充的List<Task>吗?

我可以添加一个新的TaskList<Task>并让它更新DataTable吗?

如何将数据表绑定到自定义对象列表

我可以创建从数据表填充的列表吗?

您需要这样的代码来完成所需的操作:

// Creates IEnumerable<DataRow>
var taskDataTableEnumerable = taskDataTable.AsEnumerable();
List<Task> myTaskList =
    (from item in taskDataTableEnumerable
     select new Task{
         Description = item.Field<string>("DescriptionColumnName"),
         StartDate = item.Field<DateTime>("StartDateColumnName"),
         EndDate = item.Field<DateTime>("EndDateColumnName")
    }).ToList();

我可以在列表中添加一个新的任务,让它更新数据表吗?

是的,你可以,你有以下选项:

  • 检查这个问题-转换通用列表/可枚举到数据表?,它使用Nuget实用程序FastMember来实现相同的

  • 您可以简单地为现有表创建一个新的DataRow,如下所示:

         DataRow taskDataRow = taskDataTable.NewRow();
    
  • 从新添加的任务对象中添加数据到taskDataRow,使用如下代码:

           taskDataRow["DescriptionColumnName"] = taskObject.Description
           taskDataRow["StartDateColumnName"] = taskObject.StartDate
           taskDataRow["EndDateColumnName"] = taskObject.EndDate
    

这样,新添加的Task对象列表也作为DataRow添加到DataTable,如果FastMember不适合您的用例,您需要一个不同的选项,那么可以计划使用下面的自定义代码,其中所有type T属性将转换为DataTable与适当的列名,您可以添加字段选项,如果需要,目前它是为属性:

    public static DataTable CreateTable<TDataTable>(this IEnumerable<TDataTable> collection)
    {
        // Fetch the type of List contained in the ParamValue
        var tableType = typeof(TDataTable);
        // Create DataTable which will contain data from List<T>
        var dataTable = new DataTable();
        // Fetch the Type fields count
        var columnCount = tableType.GetProperties().Count();
        var columnNameMappingDictionary = new Dictionary<string, string>();
        // Create DataTable Columns using table type field name and their types
        // Traversing through Column Collection
        for (var counter = 0; counter < columnCount; counter++)
        {
            var propertyInfo = tableType.GetProperties()[counter];                
            // Fetch DataParam attribute
            var dataParameterAttribute = propertyInfo.GetDataParameterAttribute();
            // Datatable column name based on DataParam attribute
            var columnName = (dataParameterAttribute != null) ? dataParameterAttribute.Name : propertyInfo.Name;
            columnNameMappingDictionary.Add(propertyInfo.Name,
                (dataParameterAttribute != null) ? dataParameterAttribute.Name : propertyInfo.Name);
            // Fetch the current type of a property and check whether its nullable type before adding a column
            var currentType = tableType.GetProperties()[counter].PropertyType;
            dataTable.Columns.Add(columnName, Nullable.GetUnderlyingType(currentType) ?? currentType);
        }
        // Return parameter with null value
        if (collection == null)
            return dataTable;
        // Traverse through number of entries / rows in the List
        foreach (var item in collection)
        {
            // Create a new DataRow
            var dataRow = dataTable.NewRow();
            foreach (var columnName in columnNameMappingDictionary.Select(propertyinfo => propertyinfo.Value))
            {
                dataRow[columnName] = item.GetType().GetProperty(columnName).GetValue(item) ?? DBNull.Value;
            }
            // Add Row to Table
            dataTable.Rows.Add(dataRow);
        }
        return (dataTable);
    }

//参数属性

[AttributeUsage(AttributeTargets.Property, AllowMultiple = true)]
    public class DataParamAttribute : Attribute
    {
        /// <summary>
        /// Gets or sets the name.
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// Initializes a new instance of the <see cref="DataParamAttribute"/> class.
        /// </summary>
        /// <param name="name">
        /// The name.
        /// </param>
        public DataParamAttribute(string name)
        {
            this.Name = name;
        }
    }

//获取数据参数属性

public static DataParamAttribute GetDataParameterAttribute(this PropertyInfo propertyInfo)
        {
            DataParamAttribute mappedAttribute = null;
            // Get list of Custom Attributes on a property
            var attributeArray = propertyInfo.GetCustomAttributes(false);
            // Column mapping of the ParameterAttribute
            var columnMapping =
                attributeArray.FirstOrDefault(attribute => attribute.GetType() == typeof(DataParamAttribute));
            if (columnMapping != null)
            {
                // Typecast to get the mapped attribute
                mappedAttribute = columnMapping as DataParamAttribute;
            }
            return mappedAttribute;
        }