Niceri

导航

可能是多余的

在做项目的过程中发现有一种情况,就是实体类是不确定的,没办法写出对应的实体类cs文件,那么我们怎么来在数据传输过程中形成这么个动态的类

1,首先将从数据库查出的dataset或datatable转换成 List<Dictionary<string, string>>

        /// <summary>
        /// 将DataSet转换成List集合
        /// </summary>
        /// <param name="dataSet"></param>
        /// <returns></returns>
        public static List<Dictionary<string, string>> ConvertToIEnumerable(DataSet dataSet)
        {
            List<Dictionary<string, string>> list = null;
            DataTable dt = dataSet.Tables[0];
            if (dt.Rows.Count > 0)
            {
                list = new List<Dictionary<string, string>>();
                foreach (DataRow dr in dt.Rows)
                {
                    Dictionary<string, string> dict = new Dictionary<string, string>();
                    foreach (DataColumn dc in dt.Columns)
                    {
                        dict.Add(dc.ColumnName, dr[dc.ColumnName].ToString());
                    }
                    list.Add(dict);
                }
            }
            return list;
        }

2.然后将List<Dictionary<string, string>> 转换成 IEnumerable<IDictionary>

     public IEnumerable<IDictionary> GetEnumerable(List<Dictionary<string, string>> SourceList)
        {
            for (int i = 0; i < SourceList.Count; i++)
            {
                var dict = new Dictionary<string, string>();
                dict = SourceList[i];
                yield return dict;
            }
        }

3,将 IEnumerable<IDictionary> 转换成 List<object> 这时需要用到一个 DataSourceCreator 类

    public static class DataSourceCreator
    {
        private static readonly Regex PropertNameRegex =
               new Regex(@"^[A-Za-z]+[A-Za-z1-9_]*$", RegexOptions.Singleline);
        public static List<object> ToDataSource(this IEnumerable<IDictionary> list)
        {
            IDictionary firstDict = null;
            bool hasData = false;
            foreach (IDictionary currentDict in list)
            {
                hasData = true;
                firstDict = currentDict;
                break;
            }
            if (!hasData)
            {
                return new List<object> { };
            }
            if (firstDict == null)
            {
                throw new ArgumentException("IDictionary entry cannot be null");
            }
            Type objectType = null;
            TypeBuilder tb = GetTypeBuilder(list.GetHashCode());
            ConstructorBuilder constructor =
                        tb.DefineDefaultConstructor(
                                    MethodAttributes.Public |
                                    MethodAttributes.SpecialName |
                                    MethodAttributes.RTSpecialName);
            foreach (DictionaryEntry pair in firstDict)
            {
                if (PropertNameRegex.IsMatch(Convert.ToString(pair.Key), 0))
                {
                    CreateProperty(tb,
                                    Convert.ToString(pair.Key),
                                    pair.Value == null ?
                                                typeof(object) :
                                                pair.Value.GetType());
                }
                else
                {
                    throw new ArgumentException(
                                @"Each key of IDictionary must be
                                alphanumeric and start with character.");
                }
            }
            objectType = tb.CreateType();
            return GenerateArray(objectType, list, firstDict);
        }
        private static List<object> GenerateArray(Type objectType, IEnumerable<IDictionary> list, IDictionary firstDict)
        {
            var itemsSource = new List<object>();
            foreach (var currentDict in list)
            {
                if (currentDict == null)
                {
                    throw new ArgumentException("IDictionary entry cannot be null");
                }
                object row = Activator.CreateInstance(objectType);
                foreach (DictionaryEntry pair in firstDict)
                {
                    if (currentDict.Contains(pair.Key))
                    {
                        PropertyInfo property =
                            objectType.GetProperty(Convert.ToString(pair.Key));
                        property.SetValue(
                            row,
                            Convert.ChangeType(
                                    currentDict[pair.Key],
                                    property.PropertyType,
                                    null),
                            null);
                    }
                }
                itemsSource.Add(row);
            }
            return itemsSource;
        }
        private static TypeBuilder GetTypeBuilder(int code)
        {
            AssemblyName an = new AssemblyName("TempAssembly" + code);
            AssemblyBuilder assemblyBuilder =
                AppDomain.CurrentDomain.DefineDynamicAssembly(
                    an, AssemblyBuilderAccess.Run);
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
            TypeBuilder tb = moduleBuilder.DefineType("TempType" + code
                                , TypeAttributes.Public |
                                TypeAttributes.Class |
                                TypeAttributes.AutoClass |
                                TypeAttributes.AnsiClass |
                                TypeAttributes.BeforeFieldInit |
                                TypeAttributes.AutoLayout
                                , typeof(object));
            return tb;
        }
        private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)
        {
            FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName,
                                                        propertyType,
                                                        FieldAttributes.Private);

            PropertyBuilder propertyBuilder =
                tb.DefineProperty(
                    propertyName, PropertyAttributes.HasDefault, propertyType, null);
            MethodBuilder getPropMthdBldr =
                tb.DefineMethod("get_" + propertyName,
                    MethodAttributes.Public |
                    MethodAttributes.SpecialName |
                    MethodAttributes.HideBySig,
                    propertyType, Type.EmptyTypes);
            ILGenerator getIL = getPropMthdBldr.GetILGenerator();
            getIL.Emit(OpCodes.Ldarg_0);
            getIL.Emit(OpCodes.Ldfld, fieldBuilder);
            getIL.Emit(OpCodes.Ret);
            MethodBuilder setPropMthdBldr =
                tb.DefineMethod("set_" + propertyName,
                  MethodAttributes.Public |
                  MethodAttributes.SpecialName |
                  MethodAttributes.HideBySig,
                  null, new Type[] { propertyType });
            ILGenerator setIL = setPropMthdBldr.GetILGenerator();
            setIL.Emit(OpCodes.Ldarg_0);
            setIL.Emit(OpCodes.Ldarg_1);
            setIL.Emit(OpCodes.Stfld, fieldBuilder);
            setIL.Emit(OpCodes.Ret);
            propertyBuilder.SetGetMethod(getPropMthdBldr);
            propertyBuilder.SetSetMethod(setPropMthdBldr);
        }
    }

4,描述整个过程的代码

DataSet dsResult = (查出来的表结果);
List<Dictionary<string, string>> dicList= ConvertToIEnumerable(dsResult);

List<object> list= GetEnumerable(dicList).ToDataSource();
//这样这个object就是个不用在项目中写cs文件定义的实体类
**********************
//想看具体属性的值就反射回来
foreach (object obj in list)
{
       Dictionary<string, string> result = new Dictionary<string, string>();
       System.Reflection.PropertyInfo[] properties = obj.GetType().GetProperties();
       foreach (System.Reflection.PropertyInfo item in properties)//获取该键值
       {
              string name = item.Name;
              string value = item.GetValue(model, null).ToString();
              result.Add(name, value);
       }
}    

 

posted on 2017-10-20 17:27  Niceri  阅读(287)  评论(0编辑  收藏  举报