C# 如何将数据表数据绑定到自定义对象列表
我有一个包含任务的类:C# 如何将数据表数据绑定到自定义对象列表,c#,data-binding,datatable,C#,Data Binding,Datatable,我有一个包含任务的类: class Task{ public string Description; public DateTime StartDate; public DateTime EndDate; } 我有一个SQLite数据库,它有一个名为“Task”的DataTable: 我可以创建从数据表填充的列表吗 我可以在列表中添加一个新的任务,并让它更新数据表吗 我可以创建从DataTable填充的列表吗 您需要这样的代码来完成所需的工作: // Creates IEnumer
class Task{
public string Description;
public DateTime StartDate;
public DateTime EndDate;
}
我有一个SQLite数据库,它有一个名为“Task”的DataTable
:
我可以创建从数据表填充的列表吗
我可以在列表中添加一个新的任务
,并让它更新数据表吗
我可以创建从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();
使用以下代码从新添加的任务对象向taskDataRow添加数据:
taskDataRow["DescriptionColumnName"] = taskObject.Description
taskDataRow["StartDateColumnName"] = taskObject.StartDate
taskDataRow["EndDateColumnName"] = taskObject.EndDate
这样,新添加到列表中的任务
对象也会作为数据行
添加到数据表
,以防FastMember
不适用于您的用例,并且您需要一个不同的选项,然后可能计划使用下面这样的自定义代码,如果所有的类型T
属性都将转换为具有适当列名的数据表
,您可以根据需要为字段添加选项,目前它用于属性:
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);
}
您可以将实体框架与SQLite数据库结合使用,我不知道什么是“开箱即用”的,但是有很多其他人编写的扩展方法可以做到这一点。例如:如果这个问题的上一个版本中有一个DB,那么为什么要创建任务对象呢?数据行可以表示一个任务
,您只需添加一行即可创建一个新的任务。任务对象将提供自动完成/提示,它还允许我使用任务对象内部的其他字段来完成DataGridView条目的不同区域,而无需进行大量转换。
taskDataRow["DescriptionColumnName"] = taskObject.Description
taskDataRow["StartDateColumnName"] = taskObject.StartDate
taskDataRow["EndDateColumnName"] = taskObject.EndDate
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;
}