zoukankan      html  css  js  c++  java
  • 把Linq查询返回的var类型的数据 转换为DataTable EF连接查询

    问题:我要获得一个角色下对应的所有用户,需要两表连接查询,虽然返回的只有用户数据,但是我想到若是返回的不只是用户数据,而还要加上角色信息,那么我返回什么类型呢,返回var吗,这样不行。

    于是我网上找找是否能返回DataTable呢,这样我不用创建中间类了。然后就找到下面的代码:这是别人写的,高手。

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace Common
    {
        public static class DataSetLinqOperators
        {
            public static DataTable CopyToDataTable<T>(this IEnumerable<T> source)
            {
                return new ObjectShredder<T>().Shred(source, null, null);
            }
    
            public static DataTable CopyToDataTable<T>(this IEnumerable<T> source,DataTable table, LoadOption? options)
            {
                return new ObjectShredder<T>().Shred(source, table, options);
            }
    
        }
    
        public class ObjectShredder<T>
        {
            private FieldInfo[] _fi;
            private PropertyInfo[] _pi;
            private Dictionary<string, int> _ordinalMap;
            private Type _type;
    
            public ObjectShredder()
            {
                _type = typeof(T);
                _fi = _type.GetFields();
                _pi = _type.GetProperties();
                _ordinalMap = new Dictionary<string, int>();
            }
    
            public DataTable Shred(IEnumerable<T> source, DataTable table, LoadOption? options)
            {
                if (typeof(T).IsPrimitive)
                {
                    return ShredPrimitive(source, table, options);
                }
    
    
                if (table == null)
                {
                    table = new DataTable(typeof(T).Name);
                }
    
                // now see if need to extend datatable base on the type T + build ordinal map
                table = ExtendTable(table, typeof(T));
    
                table.BeginLoadData();
                using (IEnumerator<T> e = source.GetEnumerator())
                {
                    while (e.MoveNext())
                    {
                        if (options != null)
                        {
                            table.LoadDataRow(ShredObject(table, e.Current), (LoadOption)options);
                        }
                        else
                        {
                            table.LoadDataRow(ShredObject(table, e.Current), true);
                        }
                    }
                }
                table.EndLoadData();
                return table;
            }
    
            public DataTable ShredPrimitive(IEnumerable<T> source, DataTable table, LoadOption? options)
            {
                if (table == null)
                {
                    table = new DataTable(typeof(T).Name);
                }
    
                if (!table.Columns.Contains("Value"))
                {
                    table.Columns.Add("Value", typeof(T));
                }
    
                table.BeginLoadData();
                using (IEnumerator<T> e = source.GetEnumerator())
                {
                    Object[] values = new object[table.Columns.Count];
                    while (e.MoveNext())
                    {
                        values[table.Columns["Value"].Ordinal] = e.Current;
    
                        if (options != null)
                        {
                            table.LoadDataRow(values, (LoadOption)options);
                        }
                        else
                        {
                            table.LoadDataRow(values, true);
                        }
                    }
                }
                table.EndLoadData();
                return table;
            }
    
            public DataTable ExtendTable(DataTable table, Type type)
            {
                // value is type derived from T, may need to extend table.
                foreach (FieldInfo f in type.GetFields())
                {
                    if (!_ordinalMap.ContainsKey(f.Name))
                    {
                        DataColumn dc = table.Columns.Contains(f.Name) ? table.Columns[f.Name]
                            : table.Columns.Add(f.Name, f.FieldType);
                        _ordinalMap.Add(f.Name, dc.Ordinal);
                    }
                }
                foreach (PropertyInfo p in type.GetProperties())
                {
                    if (!_ordinalMap.ContainsKey(p.Name))
                    {
                        DataColumn dc = table.Columns.Contains(p.Name) ? table.Columns[p.Name]
                            : table.Columns.Add(p.Name, p.PropertyType);
                        _ordinalMap.Add(p.Name, dc.Ordinal);
                    }
                }
                return table;
            }
    
            public object[] ShredObject(DataTable table, T instance)
            {
    
                FieldInfo[] fi = _fi;
                PropertyInfo[] pi = _pi;
    
                if (instance.GetType() != typeof(T))
                {
                    ExtendTable(table, instance.GetType());
                    fi = instance.GetType().GetFields();
                    pi = instance.GetType().GetProperties();
                }
    
                Object[] values = new object[table.Columns.Count];
                foreach (FieldInfo f in fi)
                {
                    values[_ordinalMap[f.Name]] = f.GetValue(instance);
                }
    
                foreach (PropertyInfo p in pi)
                {
                    values[_ordinalMap[p.Name]] = p.GetValue(instance, null);
                }
                return values;
            }
        }
    }

    来源:http://www.cnblogs.com/jaxu/archive/2011/08/02/2125055.html

    Jaxu的博客写挺好的,都可以看看。

    不过我最后没有用这个方法,我新建了一个中间类,来形成List返回:

    /// <summary>
            /// 根据RoleID获得该角色下的用户成员
            /// </summary>
            /// <param name="rid"></param>
            /// <returns></returns>
            public List<S_ROLE_USER_Query_Dto> GetRoleUser(int rid, string name)
            {
                IQueryable<S_ROLE_USER_Query_Dto> result = from ru in this.Context.Set<Domain.S_ROLE_USER>()
                                                           join u in this.Context.Set<Domain.S_USER>()
                                                  on new { ru.U_ID }
                                                  equals new { u.U_ID }
                                                           where (ru.R_ID == rid && (string.IsNullOrEmpty(name) ? true : (u.U_NAME.Contains(name) || u.U_REALNAME.Contains(name))))
                                                           select new S_ROLE_USER_Query_Dto
                                                           {
                                                               U_ID = ru.U_ID,
                                                               U_NAME = u.U_NAME,
                                                               U_REALNAME = u.U_REALNAME,
                                                               U_EMAIL = u.U_EMAIL,
                                                               U_MOBILE = u.U_MOBILE,
                                                               U_TEL = u.U_TEL,
                                                               R_ID = ru.R_ID
                                                           };
                return result.ToList();
            }
    

      

  • 相关阅读:
    解决绘图中闪烁的问题(C#)
    创建XML文件以及XML中的节点和更新Xml文件中的节点的值
    在C#中SendMessage和PostMessage的参数传递
    [置顶]在C#中SendMessage和PostMessage的参数传递
    C#中使用DOS命令关闭当前正在运行的程序并重新启动
    Winform中扩展Panel使之具备双缓存,防止闪屏
    用C#调用Windows API向指定窗口发送
    界面控件
    观察站模式
    利用dataview为datatable排序
  • 原文地址:https://www.cnblogs.com/xsj1989/p/7001181.html
Copyright © 2011-2022 走看看