• LINQ查询返回DataTable类型


     

     

    在使用LINQ查询的时候,一般我们会返回List<T>或IList<T>类型,如下所示:

    例1:

            public List<TSampleGetList()

            {

                using (BPDataContext db = new BPDataContext(TCTC_ConnectionStrings.connStr))

                {

                    var q = from p in db.TSample

                            select p;

                    return q.ToList();

                }

            }

    例1实现的是一个最简单的列表查询,返回的是List<TSample>类型,本身没有任何问题!但是如果现在希望查询TSample表中的指定几列,代码应该是:

    var q = from p in db.TSample

               select new

              {

                     p.FID,

                     p.FName

              };

    return q.ToList();

    现在问题是返回类型该写什么呢?new{p.FID,p.FName}已经不是TSample类型了,又不支持返回值为List<T>的!

     

    可能的解决方案是:

    方法一:

    先扩展一个类SampleEx

        public class SampleEx

        {

            public Guid FID

            {

                get;

                set;

            }

            public string FName

            {

                get;

                set;

            }

        }

    然后返回List<SampleEx>类型

            public List<SampleExGetList()

            {

                using (BPDataContext db = new BPDataContext(TCTC_ConnectionStrings.connStr))

                {

                    var q = from p in db.TSample

                            select new SampleEx()

                            {

                                FID = p.FID,

                                FName = p.FName

                            };

                    return q.ToList();

                }

            }

    这样就达到了我们想要的目标。

     

    问题是解决了,但是再仔细想想这样的解决方案似乎可行性不强。因为在实际开发中我们经常查询两个表join查询,那么重新组合的字段就比较多了,要每个都去扩展单独的类,工作量太大!有些人可能会想到用试图,然后dbml会自动帮我们生成类,但是这个工作量也应该不小,天天建试图,要频繁跟新dbml文件的方式不怎么合理!最期望的方式就是不用构造自定义类型,经过转换返回我们需要的类型!

         下面通过一个方法来实现返回DataTable类型:

            /// <summary>

            /// LINQ返回DataTable类型

            /// </summary>

            /// <typeparam name="T"> </typeparam>

            /// <param name="varlist"> </param>

            /// <returns> </returns>

            public static DataTable ToDataTable<T>(IEnumerable<Tvarlist)

            {

                DataTable dtReturn = new DataTable();

     

                // column names

                PropertyInfo[] oProps = null;

     

                if (varlist == null)

                    return dtReturn;

     

                foreach (T rec in varlist)

                {

                    if (oProps == null)

                    {

                        oProps = ((Type)rec.GetType()).GetProperties();

                        foreach (PropertyInfo pi in oProps)

                        {

                            Type colType = pi.PropertyType;

     

                            if ((colType.IsGenericType) && (colType.GetGenericTypeDefinition()

                                 == typeof(Nullable<>)))

                            {

                                colType = colType.GetGenericArguments()[0];

                            }

     

                            dtReturn.Columns.Add(new DataColumn(pi.NamecolType));

                        }

                    }

     

                    DataRow dr = dtReturn.NewRow();

     

                    foreach (PropertyInfo pi in oProps)

                    {

                        dr[pi.Name] = pi.GetValue(recnull) == null ? DBNull.Value : pi.GetValue

                        (recnull);

                    }

     

                    dtReturn.Rows.Add(dr);

                }

                return dtReturn;

            }

     

     

    如何使用?如下示例:

            /// <summary>

            /// 根据获取多个器具信息

            /// </summary>

            /// <param name="IDs"></param>

            /// <returns></returns>

            public DataTable GetByIDs(List<stringIDs)

            {

                using (BPDataContext db = new BPDataContext(TCTC_ConnectionStrings.connStr))

                {

                    var p = (from c in db.TSample

                             where IDs.Contains(c.FID.ToString())

                             select new

                             {

                                 c.FID,

                                 c.FName,

                                 c.FCode,

                                 c.FType,

                                 c.FProductUnit,

                                 c.FDeviceNo

                             }).ToList();

                    return LinqToDataTable.ToDataTable(p);

                }

            }

        到这里就达到了我们预期的方式!返回DataTable,那么对后面数据源直接绑定,或序列化为Json都非常方便了!

     

    序列化DataTable为Json格式的方法直接用微软的JavaScriptSerializer.Serialize()方法是会有问题的,我们需要自己写方法序列化,

    序列化代码详见:http://xuzhihong1987.blog.163.com/blog/static/26731587201101913722238/

    参考资料:

    -------------------------------------------------------------------------------------------------------------------------------------------------
    数据库优化
    数据库教程
    数据库实战经验分享博客

    百度云下载

    评测


  • 相关阅读:
    绘制图形(-)
    数字金字塔
    固定行数输出
    [原创]java WEB学习笔记70:Struts2 学习之路-- 输入验证,声明式验证,声明是验证原理
    [原创]java WEB学习笔记70:Struts2 学习之路-- struts2拦截器源码分析,运行流程
    [原创]java WEB学习笔记69:Struts2 学习之路-- 消息处理与国际化,概述,配置国际资源文件,访问国际化消息,通过超链接切换语言
    [原创]java WEB学习笔记68:Struts2 学习之路-- 类型转换与复杂属性配合使用
    [原创]java WEB学习笔记67:Struts2 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器
    [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈
    [原创]java WEB学习笔记65:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) ModelDriven拦截器 paramter 拦截器
  • 原文地址:https://www.cnblogs.com/longle/p/linqtodatatable.html
Copyright © 2020-2023  润新知