把linq查询返回的var类型的数据转换为datatable

邢帅杰 邢帅杰     2022-09-04     621

关键词:

问题:我要获得一个角色下对应的所有用户,需要两表连接查询,虽然返回的只有用户数据,但是我想到若是返回的不只是用户数据,而还要加上角色信息,那么我返回什么类型呢,返回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语句查询

...具与关键技术:VS作者:老岑撰写时间:2019年4月3日这个查询是需要添加数据库实体数据模型的,这个就不多讲了Linq语句查询,目前的学习进度来说也就是我们的单表和多表查询。它为匿名类型查询提供了一种很方便的方法,可... 查看详情

从 Linq 查询返回类型化的 DataTable

】从Linq查询返回类型化的DataTable【英文标题】:ReturntypedDataTablefromLinqQuery【发布时间】:2010-11-0609:46:49【问题描述】:我在XML中有一个(断开的)类型化数据集,我在LINQ中查询:varproductlist=fromprdsindsProducts.Products.AsEnumerable()where... 查看详情

如何将 linq var 数据类型传递给方法? [复制]

...很严重的问题,希望你能帮我解决一下有如下的linq-to-sql查询,很简单:vari=fromcrindb.Compro 查看详情

第十二章sql聚合函数variance,var_samp,var_pop

...OP的计算是:这些方差聚合函数可以在引用表或视图的SELECT查询或子查询中使用。它们可以在SELECT列表或HAVING子句中与普通字段值一起出现。这些方差聚合函数不能在WHERE子句中使用。它们不能在JOIN的ON子句中使用,除非SELECT是子... 查看详情

linq怎么转换日期为字符串

....userwherei.CreateDate.ToString().StartWith("2012")selecti;上面查询创建日期为2012的所有用户,可是报错,我该怎样将日期转换为字符串呢?谢谢。Add_Date=Date.ToString("yyyy-MM-ddhh:mm:ss")Add_Date=Date.ToString("MM/dd/yyyy")在LINQ中,取值设置格式... 查看详情

找不到 linq 查询输出的正确返回类型

】找不到linq查询输出的正确返回类型【英文标题】:Can\'tfindtherightreturntypeforalinqqueryoutput【发布时间】:2021-04-1314:50:59【问题描述】:我有以下方法可以返回LINQ查询的输出。该方法工作得很好,但我有动态作为返回类型,因为... 查看详情

将两个查询的左外连接转换为 LINQ

】将两个查询的左外连接转换为LINQ【英文标题】:ConvertingleftouterjoinontwoqueriestoLINQ【发布时间】:2015-09-0710:59:41【问题描述】:我有下面的sql查询,我想将其转换为LINQ以获得完全相同的结果并由下面的查询返回select*from(selectdisti... 查看详情

linq的实例(代码片段)

LINQ查询表达式语法:类型查询变量=from临时变量in集合对象或数据库对象[where条件表达式][orderby条件]select临时变量中被查询的值[groupby条件]查询变量的作用是保存查询,而非查询结果查询表达式语法要点总结:1、查询表达式语法... 查看详情

如何将二进制转换为字节[]?我收到了这个:无法将类型“System.Data.Linq.Binary”隐式转换为“byte[]”

】如何将二进制转换为字节[]?我收到了这个:无法将类型“System.Data.Linq.Binary”隐式转换为“byte[]”【英文标题】:HowtoconvertBinarytobyte[]?Ireceivedthis:Cannotimplicitlyconverttype‘System.Data.Linq.Binary’to‘byte[]’【发布时间】:2016-04-0714:2... 查看详情

返回 LINQ 查询结果的控制器方法

】返回LINQ查询结果的控制器方法【英文标题】:controllermethodwhichreturnsLINQqueryresult【发布时间】:2022-01-1517:39:33【问题描述】:我正在创建一个返回LINQ查询结果的方法。我将其创建为单独的方法,因为多个视图将需要相同的查询... 查看详情

将 Linq 查询转换为数据库视图

】将Linq查询转换为数据库视图【英文标题】:TranslateaLinqqueryintoadatabaseView【发布时间】:2015-12-2210:14:57【问题描述】:我的数据库中有一个表TestPack,该表与表Documentation和InternalWalk有1-N关系。下面的代码通过从数据库中获取所... 查看详情

linq怎么转换日期为字符串

....userwherei.CreateDate.ToString().StartWith("2012")selecti;上面查询创建日期为2012的所有用户,可是报错,我该怎样将日期转换为字符串呢?谢谢。参考技术Afromiindb.userwherei.CreateDate.Year==2012selecti;试试这个吧如果CreateDate的类型是DataTim... 查看详情

把一个list类型强制转换为一个对象类型是怎么实现的

...一个User类,有私有属性name,sex,birth,Listlist是用从数据库查询得到的结果,该表有name,sex,birth几个列,几行数据。我用while(inti=0;i<list.size();i++)Useruser=(User)list(i);这一步是怎么转换的?如果list的各项属性和user的各项属性不一样是... 查看详情

LINQ/LinqPad:相同的查询不同的结果

】LINQ/LinqPad:相同的查询不同的结果【英文标题】:LINQ/LinqPad:samequerydifferentresults【发布时间】:2012-06-2202:42:00【问题描述】:因此,我们将完全相同的查询从LinqPad复制并粘贴到我们的EF4.3应用程序中,指向完全相同的数据库并... 查看详情

sql字符串转换成日期

...转换 expression 的整数表达式。如果样式为NULL,则返回NULL。该范围是由 data_type 确定的。返回类型:返回转换为 data_type 的 expression。扩展资料:如果 expression 为date或datetime数据类型,则其他值... 查看详情

将 Linq 查询结果转换为字典

】将Linq查询结果转换为字典【英文标题】:ConvertLinqQueryResulttoDictionary【发布时间】:2010-10-3112:49:55【问题描述】:我想使用LinqtoSQL向数据库添加一些行,但我想在添加行之前进行“自定义检查”以了解是否必须添加、替换或忽... 查看详情

什么是linq,它做什么?[关闭](代码片段)

...适用于数据库,但它有什么作用?答案LINQ代表语言集成查询。Microsoft语言开发人员提供了一种直接在其语言中表达查询的方法(例如C#和VisualBasic),而不是编写YAQL(又一种查询语言)。形成这些查询的技术不依赖于被查询事... 查看详情

sql怎么样把numeric类型的数据转换为varchar类型的数据

CAST和CONVERT将某种数据类型的表达式显式转换为另一种数据类型。CAST和CONVERT提供相似的功能。语法:--使用CAST:CAST ( expression ASdata_type )--使用CONVERT:CONVERT(data_type[(length)],expression[,style])参数:expression是任何有效... 查看详情