把Linq查询返回的var类型的数据 转换为DataTable
Posted 邢帅杰
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了把Linq查询返回的var类型的数据 转换为DataTable相关的知识,希望对你有一定的参考价值。
问题:我要获得一个角色下对应的所有用户,需要两表连接查询,虽然返回的只有用户数据,但是我想到若是返回的不只是用户数据,而还要加上角色信息,那么我返回什么类型呢,返回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(); }
以上是关于把Linq查询返回的var类型的数据 转换为DataTable的主要内容,如果未能解决你的问题,请参考以下文章
在 LINQ 查询中将 KeyValuePair 转换为匿名类型