Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 精灵_C#_Linq_Generics_Lambda_Datatable - Fatal编程技术网

C# 精灵

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

或者,我还考虑添加一个单独的参数,该参数保存要从DataTable中读取的实际列名。在这种情况下,您不必使用“row[property.Name]”,而是可以对特定属性使用row[attribute.Name]”或类似的内容

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];
}