zoukankan      html  css  js  c++  java
  • 通过反射调用泛型参数方法

    最近在学习EDM,发现LinqPad是一个好东西,可以运行Linq To Sql, Entity SQL Language脚本,但不会用ESql查询功能,始终报错,半天找不到门道,一怒之下决定自己写一个小型的ESql查询器。

    将比较重要的知识点归纳了一下,贴几段重要的代码,以免下次遗忘。

            private void btnRunQuery_Click(object sender, EventArgs e)
            {
                if (cmbEntitySet.SelectedItem == null)
                    return;
                Type typeObjectQuery = (cmbEntitySet.SelectedItem as ImageComboBoxItem).Value as Type;
                Type typeEntity = typeObjectQuery.GetGenericArguments()[0];

                using (cdms3Entities ctx = new cdms3Entities())
                {
                    //通过反射调用ObjectQuery<T> CreateQuery<T>(string queryString, params ObjectParameter[] parameters);
                    MethodInfo miCreateQuery = ctx.GetType().GetMethod("CreateQuery", BindingFlags.Instance | BindingFlags.Public);
                    //设置CreateQuery<T>中的T泛型参数为typeEntity所指的实体对象类型
                    miCreateQuery = miCreateQuery.MakeGenericMethod(typeEntity);
                    //创建调用参数,传入Entity SQL Language语句
                    object[] args = new object[] { mmeESql.Text, new ObjectParameter[] { } };
                    //调用CreateQuery函数,返回一个ObjectQuery<T>类型的对象,ObjectQuery<T>泛型类由ObjectQuery类派生,所以可转换为ObjectQuery类型
                    ObjectQuery oq = miCreateQuery.Invoke(ctx, args) as ObjectQuery;

                    //如果下列检查框中有选择需要Include到查询中的实体对象
                    if (cmbIncludes.Properties.GetCheckedItems() != "")
                    {
                        //获取ObjectQuery<T> Include(string path);函数,注意函数的返回值类型是泛型,但函数并不是泛型,所以不需要也不能对其调用MakeGenericMethod方法
                        MethodInfo miInclude = oq.GetType().GetMethod("Include", BindingFlags.Instance | BindingFlags.Public);
                        foreach (CheckedListBoxItem item in cmbIncludes.Properties.Items)
                        {
                            if (item.CheckState == CheckState.Checked)
                            {
                                EntityObjectInfo eo = item.Value as EntityObjectInfo;
                                args = new object[] { eo.Path };
                                //调用ObjectQuery<T>.Include方法
                                oq = miInclude.Invoke(oq, args) as ObjectQuery;
                            }
                        }
                    }

                    //下面调用ObjectQuery<T>.ToList()方法来获取查询结果。
                    //特别要注意的是ToList()方法是一个扩展方法,方法原型是:public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source);位于System.Linq.Enumerable类
                    //所以反射时应当对Enumerable类进行,且该方法为公共静态方法。
                    MethodInfo miToList = typeof(Enumerable).GetMethod("ToList", BindingFlags.Static | BindingFlags.Public);
                    miToList = miToList.MakeGenericMethod(typeEntity);
                    args = new object[] { oq };
                    object o = miToList.Invoke(null, args);
                    //var q = ctx.CreateQuery<Department>(mmeESql.Text);
                    mmeTraceSql.Text = oq.ToTraceString();
                    grdResultData.DataSource = o;
                }

            }

  • 相关阅读:
    接口自动化架构-获取用例
    Windows性能监控工具Perfmon使用指南
    接口自动化架构1-setting
    多进程
    线程锁、守护线程
    多线程
    xlrd模块
    封装写日志的类
    封装redis
    继承
  • 原文地址:https://www.cnblogs.com/wiseant/p/1624088.html
Copyright © 2011-2022 走看看