C# 精灵
或者,我还考虑添加一个单独的参数,该参数保存要从DataTable中读取的实际列名。在这种情况下,您不必使用“row[property.Name]”,而是可以对特定属性使用row[attribute.Name]”或类似的内容C# 精灵,c#,linq,generics,lambda,datatable,C#,Linq,Generics,Lambda,Datatable,或者,我还考虑添加一个单独的参数,该参数保存要从DataTable中读取的实际列名。在这种情况下,您不必使用“row[property.Name]”,而是可以对特定属性使用row[attribute.Name]”或类似的内容 public static class DataTableExtensions { [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)] pu
public static class DataTableExtensions
{
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
public sealed class IgnoreAttribute : Attribute { public IgnoreAttribute() { } }
private static Dictionary<Type, IList<PropertyInfo>> typeDictionary = new Dictionary<Type, IList<PropertyInfo>>();
public static IList<PropertyInfo> GetPropertiesForType<T>()
{
var type = typeof(T);
if (!typeDictionary.ContainsKey(typeof(T)))
typeDictionary.Add(type, type.GetProperties().ToList());
return typeDictionary[type];
}
public static IList<T> ToList<T>(this DataTable table) where T : new()
{
IList<PropertyInfo> properties = GetPropertiesForType<T>();
IList<T> result = new List<T>();
foreach (var row in table.Rows)
result.Add(CreateItemFromRow<T>((DataRow)row, properties));
return result;
}
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
{
T item = new T();
foreach (var property in properties)
{
// Only load those attributes NOT tagged with the Ignore Attribute
var atr = property.GetCustomAttribute(typeof(IgnoreAttribute));
if (atr == null)
property.SetValue(item, row[property.Name], null);
}
return item;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class SimppleMapperAttribute: Attribute
{
public string HeaderName { get; set; }
}
public static class SimpleMapper
{
#region properties
public static bool UseDeferredExecution { get; set; } = true;
#endregion
#region public_interface
public static IEnumerable<T> MapWhere<T>(this DataTable table, Func<T, bool> sortExpression) where T:new()
{
var result = table.Select().Select(row => ConvertRow<T>(row, table.Columns, typeof(T).GetProperties())).Where((t)=>sortExpression(t));
return UseDeferredExecution ? result : result.ToArray();
}
public static IEnumerable<T> Map<T>(this DataTable table) where T : new()
{
var result = table.Select().Select(row => ConvertRow<T>(row, table.Columns, typeof(T).GetProperties()));
return UseDeferredExecution ? result : result.ToArray();
}
#endregion
#region implementation_details
private static T ConvertRow<T>(DataRow row, DataColumnCollection columns, System.Reflection.PropertyInfo[] p_info) where T : new()
{
var instance = new T();
foreach (var info in p_info)
{
if (columns.Contains(GetMappingName(info))) SetProperty(row, instance, info);
}
return instance;
}
private static void SetProperty<T>(DataRow row, T instance, System.Reflection.PropertyInfo info) where T : new()
{
string mp_name = GetMappingName(info);
object value = row[mp_name];
info.SetValue(instance, value);
}
private static string GetMappingName(System.Reflection.PropertyInfo info)
{
SimppleMapperAttribute attribute = info.GetCustomAttributes(typeof(SimppleMapperAttribute),true).Select((o) => o as SimppleMapperAttribute).FirstOrDefault();
return attribute == null ? info.Name : attribute.HeaderName;
}
#endregion
}
公共静态类DataTableExtensions
{
[AttributeUsage(AttributeTargets.Property,Inherited=false,AllowMultiple=true)]
公共密封类IgnoreAttribute:属性{public IgnoreAttribute(){}
私有静态字典typeDictionary=新字典();
公共静态IList GetPropertiesForType()
{
var类型=类型(T);
if(!typeDictionary.ContainsKey(typeof(T)))
添加(type,type.GetProperties().ToList());
返回typeDictionary[type];
}
公共静态IList ToList(此数据表),其中T:new()
{
IList properties=GetPropertiesForType();
IList结果=新列表();
foreach(表中的变量行。行)
添加(CreateItemFromRow((DataRow)行,属性));
返回结果;
}
私有静态T CreateItemFromRow(DataRow行,IList属性),其中T:new()
{
T项=新的T();
foreach(属性中的var属性)
{
//仅加载未使用“忽略”属性标记的属性
var atr=property.GetCustomAttribute(typeof(IgnoreAttribute));
如果(atr==null)
property.SetValue(项,行[property.Name],null);
}
退货项目;
}
}
迟到,但这可能很有用。可以使用以下方法调用:
table.Map();
或使用Func调用以筛选值
您甚至可以通过设置属性上的属性来更改type属性和DataColumn标头之间的映射名称
public static class DataTableExtensions
{
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
public sealed class IgnoreAttribute : Attribute { public IgnoreAttribute() { } }
private static Dictionary<Type, IList<PropertyInfo>> typeDictionary = new Dictionary<Type, IList<PropertyInfo>>();
public static IList<PropertyInfo> GetPropertiesForType<T>()
{
var type = typeof(T);
if (!typeDictionary.ContainsKey(typeof(T)))
typeDictionary.Add(type, type.GetProperties().ToList());
return typeDictionary[type];
}
public static IList<T> ToList<T>(this DataTable table) where T : new()
{
IList<PropertyInfo> properties = GetPropertiesForType<T>();
IList<T> result = new List<T>();
foreach (var row in table.Rows)
result.Add(CreateItemFromRow<T>((DataRow)row, properties));
return result;
}
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
{
T item = new T();
foreach (var property in properties)
{
// Only load those attributes NOT tagged with the Ignore Attribute
var atr = property.GetCustomAttribute(typeof(IgnoreAttribute));
if (atr == null)
property.SetValue(item, row[property.Name], null);
}
return item;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class SimppleMapperAttribute: Attribute
{
public string HeaderName { get; set; }
}
public static class SimpleMapper
{
#region properties
public static bool UseDeferredExecution { get; set; } = true;
#endregion
#region public_interface
public static IEnumerable<T> MapWhere<T>(this DataTable table, Func<T, bool> sortExpression) where T:new()
{
var result = table.Select().Select(row => ConvertRow<T>(row, table.Columns, typeof(T).GetProperties())).Where((t)=>sortExpression(t));
return UseDeferredExecution ? result : result.ToArray();
}
public static IEnumerable<T> Map<T>(this DataTable table) where T : new()
{
var result = table.Select().Select(row => ConvertRow<T>(row, table.Columns, typeof(T).GetProperties()));
return UseDeferredExecution ? result : result.ToArray();
}
#endregion
#region implementation_details
private static T ConvertRow<T>(DataRow row, DataColumnCollection columns, System.Reflection.PropertyInfo[] p_info) where T : new()
{
var instance = new T();
foreach (var info in p_info)
{
if (columns.Contains(GetMappingName(info))) SetProperty(row, instance, info);
}
return instance;
}
private static void SetProperty<T>(DataRow row, T instance, System.Reflection.PropertyInfo info) where T : new()
{
string mp_name = GetMappingName(info);
object value = row[mp_name];
info.SetValue(instance, value);
}
private static string GetMappingName(System.Reflection.PropertyInfo info)
{
SimppleMapperAttribute attribute = info.GetCustomAttributes(typeof(SimppleMapperAttribute),true).Select((o) => o as SimppleMapperAttribute).FirstOrDefault();
return attribute == null ? info.Name : attribute.HeaderName;
}
#endregion
}
[AttributeUsage(AttributeTargets.Property)]
公共类SimppleMapperAttribute:属性
{
公共字符串头名称{get;set;}
}
公共静态类SimpleMapper
{
#区域属性
公共静态bool usedferredexecution{get;set;}=true;
#端区
#区域公共接口
公共静态IEnumerable映射where(此DataTable表,Func sortExpression),其中T:new()
{
var result=table.Select().Select(row=>ConvertRow(row,table.Columns,typeof(T).GetProperties())。其中((T)=>sortExpression(T));
返回UseDeferreExecution?结果:result.ToArray();
}
公共静态IEnumerable映射(此数据表),其中T:new()
{
var result=table.Select().Select(row=>ConvertRow(row,table.Columns,typeof(T).GetProperties());
返回UseDeferreExecution?结果:result.ToArray();
}
#端区
#地区实施详情
私有静态T ConvertRow(DataRow行、DataColumnCollection列、System.Reflection.PropertyInfo[]p_info),其中T:new()
{
var instance=newt();
foreach(p_信息中的var信息)
{
if(columns.Contains(GetMappingName(info)))SetProperty(行、实例、信息);
}
返回实例;
}
私有静态void SetProperty(DataRow行,T实例,System.Reflection.PropertyInfo信息),其中T:new()
{
字符串mp_name=GetMappingName(信息);
对象值=行[mp_名称];
info.SetValue(实例,值);
}
私有静态字符串GetMappingName(System.Reflection.PropertyInfo信息)
{
SimppleMapperAttribute=info.GetCustomAttributes(typeof(SimppleMapperAttribute),true)。选择((o)=>o作为SimppleMapperAttribute)。FirstOrDefault();
返回属性==null?信息名称:attribute.HeaderName;
}
#端区
}
这里有一个简单的方法,可以在c#中使用Where条件转换为泛型列表
List<Filter> filter = ds.Tables[0].AsEnumerable()
.Where(x => x.Field<int>("FilterID") == 5)
.Select(row => new Filter
{
FilterID = row.Field<int>("FilterID"),
FilterName = row.Field<string>("FilterName")
}).ToList();
放置程序包:
using System.Linq;
using System.Collections.Generic;
下面是将DataTable转换为泛型类型列表的最快的无循环解决方案
public static List<T> ConvertDataTable<T>(DataTable SourceData, Func<DataRow, T> RowConverter)
{
List<T> list = new List<T>();
if (SourceData == null || SourceData.Rows.Count < 1)
return list;
IEnumerable<T> enumerable = SourceData.AsEnumerable().Select(RowConverter);
if (enumerable == null)
return list;
return new List<T>(enumerable);
}
公共静态列表转换器DataTable(DataTable SourceData,Func RowConverter)
{
列表=新列表();
if(SourceData==null | | SourceData.Rows.Count<1)
退货清单;
IEnumerable enumerable=SourceData.AsEnumerable().Select(行转换器);
if(可枚举==null)
退货清单;
返回新列表(可枚举);
}
这就是这个功能的实现
public static List<T> ExecuteListOfObject<T>(DataTable SourceData)
{
return ConvertDataTable(SourceData, ConvertRecord<T>);
}
public static T ConvertRecord<T>(DataRow drData)
{
if (drData == null || drData[0] == DBNull.Value)
return default(T);
return (T)drData[0];
}
publicstaticlist ExecuteListOfObject(DataTable SourceData)
{
返回ConvertDataTable(SourceData,ConvertRecord);
}
公共静态转换记录(数据行drData)
{
if(drData==null | | drData[0]==DBNull.Value)
返回默认值(T);
返回(T)drData[0];
}
这个问题是要解决还是错了?:)@marc garvell:我也想处理datatable数据…您有一个构造函数…默认的构造函数。ConvertAll()
作为列表
方法。它不是一个扩展方法,也不是IEnumerable
明确定义它。在IEnumerable
中,最接近的类似方法是选择()
@Jeff:那么列类型不可为空呢…比如CardName=row.Field(0)我提到它被大大缩短了。从表面上看,它看起来没什么不同。我的意思是它可以写得更高效。您最初的方法创建了两个不同的列表实例,迭代表的长度两次。这种方法一次完成转换。正如您所知。@naveen:strings当然是可以为null的,它们是引用类型,而不是可为null的值类型。您有什么特别想做的吗?@jeff:我想捕获null或empty并传递string“notfound”“@naveen:我会添加一个案例来演示你如何处理这个问题。谢谢你,伙计。这对我很有帮助。在CreateItemFromRow
中,您应该检查是否(row.Table.Columns.Contains(property.Name))
,然后发出property.SetValue(..
。这将确保在出现异常时不会引发异常
public DataTable getTable()
{
DataTable dt = new DataTable();
dt.Columns.Add(new DataColumn("ItemCode", typeof(string)));
dt.Columns.Add(new DataColumn("Cost", typeof(string)));
DataRow dr;
for (int i = 0; i < 10; i++)
{
dr = dt.NewRow();
dr[0] = "ItemCode" + (i + 1);
dr[1] = "Cost" + (i + 1);
dt.Rows.Add(dr);
}
return dt;
}
DataTable dt = getTable();
List<Item> lst = dt.ToCollection<Item>();
foreach (Item cn in lst)
{
Response.Write(cn.ToString() + "<BR/>");
}
public static class DataTableExtensions
{
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
public sealed class IgnoreAttribute : Attribute { public IgnoreAttribute() { } }
private static Dictionary<Type, IList<PropertyInfo>> typeDictionary = new Dictionary<Type, IList<PropertyInfo>>();
public static IList<PropertyInfo> GetPropertiesForType<T>()
{
var type = typeof(T);
if (!typeDictionary.ContainsKey(typeof(T)))
typeDictionary.Add(type, type.GetProperties().ToList());
return typeDictionary[type];
}
public static IList<T> ToList<T>(this DataTable table) where T : new()
{
IList<PropertyInfo> properties = GetPropertiesForType<T>();
IList<T> result = new List<T>();
foreach (var row in table.Rows)
result.Add(CreateItemFromRow<T>((DataRow)row, properties));
return result;
}
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
{
T item = new T();
foreach (var property in properties)
{
// Only load those attributes NOT tagged with the Ignore Attribute
var atr = property.GetCustomAttribute(typeof(IgnoreAttribute));
if (atr == null)
property.SetValue(item, row[property.Name], null);
}
return item;
}
}
[AttributeUsage(AttributeTargets.Property)]
public class SimppleMapperAttribute: Attribute
{
public string HeaderName { get; set; }
}
public static class SimpleMapper
{
#region properties
public static bool UseDeferredExecution { get; set; } = true;
#endregion
#region public_interface
public static IEnumerable<T> MapWhere<T>(this DataTable table, Func<T, bool> sortExpression) where T:new()
{
var result = table.Select().Select(row => ConvertRow<T>(row, table.Columns, typeof(T).GetProperties())).Where((t)=>sortExpression(t));
return UseDeferredExecution ? result : result.ToArray();
}
public static IEnumerable<T> Map<T>(this DataTable table) where T : new()
{
var result = table.Select().Select(row => ConvertRow<T>(row, table.Columns, typeof(T).GetProperties()));
return UseDeferredExecution ? result : result.ToArray();
}
#endregion
#region implementation_details
private static T ConvertRow<T>(DataRow row, DataColumnCollection columns, System.Reflection.PropertyInfo[] p_info) where T : new()
{
var instance = new T();
foreach (var info in p_info)
{
if (columns.Contains(GetMappingName(info))) SetProperty(row, instance, info);
}
return instance;
}
private static void SetProperty<T>(DataRow row, T instance, System.Reflection.PropertyInfo info) where T : new()
{
string mp_name = GetMappingName(info);
object value = row[mp_name];
info.SetValue(instance, value);
}
private static string GetMappingName(System.Reflection.PropertyInfo info)
{
SimppleMapperAttribute attribute = info.GetCustomAttributes(typeof(SimppleMapperAttribute),true).Select((o) => o as SimppleMapperAttribute).FirstOrDefault();
return attribute == null ? info.Name : attribute.HeaderName;
}
#endregion
}
List<Filter> filter = ds.Tables[0].AsEnumerable()
.Where(x => x.Field<int>("FilterID") == 5)
.Select(row => new Filter
{
FilterID = row.Field<int>("FilterID"),
FilterName = row.Field<string>("FilterName")
}).ToList();
public class Filter
{
public int FilterID { get; set; }
public string FilterName { get; set; }
}
using System.Linq;
using System.Collections.Generic;
public static List<T> ConvertDataTable<T>(DataTable SourceData, Func<DataRow, T> RowConverter)
{
List<T> list = new List<T>();
if (SourceData == null || SourceData.Rows.Count < 1)
return list;
IEnumerable<T> enumerable = SourceData.AsEnumerable().Select(RowConverter);
if (enumerable == null)
return list;
return new List<T>(enumerable);
}
public static List<T> ExecuteListOfObject<T>(DataTable SourceData)
{
return ConvertDataTable(SourceData, ConvertRecord<T>);
}
public static T ConvertRecord<T>(DataRow drData)
{
if (drData == null || drData[0] == DBNull.Value)
return default(T);
return (T)drData[0];
}