/// <summary> /// 将OutPut参数赋值到实体 /// </summary> /// <typeparam name="TEntity">实体类</typeparam> /// <param name="map">实体类结构</param> /// <param name="lstParam">SQL参数列表</param> /// <param name="entity">实体类</param> public void SetParamToEntity<TEntity>(SetPhysicsMap map, List<DbParameter> lstParam, TEntity entity) where TEntity : class, new() { if (entity == null) { return; } foreach (var kic in map.MapList.Where(o => o.Value.Field.IsOutParam)) { var oVal = ConvertHelper.ConvertType(lstParam.Find(o => o.ParameterName == ParamsPrefix + kic.Value.Field.Name).Value, kic.Key.PropertyType); PropertySetCacheManger.Cache(kic.Key, entity, oVal); } }
/// <summary> 生成赋值操作 </summary> private static string CreateSwitchCase(SetPhysicsMap setPhysicsMap) { var sb = new StringBuilder(); foreach (var map in setPhysicsMap.MapList) { // 字段名 var filedName = map.Value.Field.IsFun ? map.Key.Name : map.Value.Field.Name; // 类型转换 var propertyType = map.Key.PropertyType.GetNullableArguments(); // 字段赋值 var propertyAssign = $"entity.{map.Key.Name}"; // case 字段名 sb.Append($"\t\t\tcase \"{filedName.ToUpper()}\":\r\n\t\t\t\t"); // 使用FS的ConvertHelper 进行类型转换泛型类型 if (propertyType.IsGenericType) { if (propertyType.IsArray) // 数组类型 { var asType = $"{propertyType.GetGenericArguments()[0].FullName}[]"; sb.Append($"{propertyAssign} = ConvertHelper.ConvertType(col,typeof({asType})) as {asType}; "); } else // List集合 { sb.Append($"{propertyAssign} = StringHelper.ToList<{propertyType.GetGenericArguments()[0].FullName}>(col.ToString()); "); } } else { // 字符串不需要处理 if (propertyType == typeof(string)) { sb.Append($"{propertyAssign} = col.ToString();"); } else if (propertyType.IsEnum) { sb.Append($"if (typeof({propertyType.FullName}).GetEnumUnderlyingType() == col.GetType()) {{ {propertyAssign} = ({propertyType.FullName})col; }} else {{ {propertyType.FullName} {filedName}_Out; if (System.Enum.TryParse(col.ToString(), out {filedName}_Out)) {{ {propertyAssign} = {filedName}_Out; }} }}"); } else if (propertyType == typeof(bool)) { sb.Append($"{propertyAssign} = ConvertHelper.ConvertType(col,false);"); } else if (!propertyType.IsClass) { sb.Append($"if (col is {propertyType.FullName}) {{ {propertyAssign} = ({propertyType.FullName})col; }} else {{ {propertyType.FullName} {filedName}_Out; if ({propertyType.FullName}.TryParse(col.ToString(), out {filedName}_Out)) {{ {propertyAssign} = {filedName}_Out; }} }}"); } } // 退出case sb.AppendLine("break;"); } return(sb.ToString()); }
/// <summary> /// 存储过程创建SQL 输入、输出参数化 /// </summary> /// <typeparam name="TEntity">实体类</typeparam> /// <param name="map">实体类结构</param> /// <param name="entity">实体类</param> public List<DbParameter> InitParam<TEntity>(SetPhysicsMap map, TEntity entity) where TEntity : class, new() { var lstParam = new List<DbParameter>(); if (entity == null) { return lstParam; } foreach (var kic in map.MapList.Where(o => o.Value.Field.IsInParam || o.Value.Field.IsOutParam)) { var obj = PropertyGetCacheManger.Cache(kic.Key, entity); lstParam.Add(CreateDbParam(kic.Value.Field.Name, obj, kic.Key.PropertyType, kic.Value.Field.IsOutParam)); } return lstParam; }
/// <summary> 生成CreateToEntity转换方法 </summary> private string CreateToEntity(Type entityType, SetPhysicsMap setPhysicsMap) { var sb = new StringBuilder(); sb.AppendFormat(@" public static {0} ToEntity(MapingData[] mapData, int rowsIndex = 0) {{ if ( mapData == null || mapData.Length == 0 || mapData[0].DataList.Count == 0) {{ return null; }} var entity = new {0}(); foreach (var map in mapData) {{ var col = map.DataList[rowsIndex]; if (col == null) {{ continue; }} switch (map.ColumnName.ToUpper()) {{ {1} }} }} return entity; }}", entityType.FullName, CreateSwitchCase(setPhysicsMap)); return(sb.ToString()); }
/// <summary> /// 根据TEntity实体,动态生成派生类 /// </summary> private Type CreateEntity <TEntity>() { var entityType = typeof(TEntity); var setPhysicsMap = new SetPhysicsMap(entityType); var clsName = entityType.Name + "ByDataRow"; // 类名 var sb = new StringBuilder(); sb.AppendLine("using System;"); sb.AppendLine("using System.Collections.Generic;"); sb.AppendLine("using FS.Utils.Common;"); sb.AppendLine("using FS.Infrastructure;"); sb.AppendLine($"namespace {entityType.Namespace}\r\n{{"); sb.AppendLine($"public class {clsName} : {entityType.FullName}\r\n{{"); // DataRow构造 sb.AppendLine(CreateToList(entityType)); // DataTable构造 sb.AppendLine(CreateToEntity(entityType, setPhysicsMap)); sb.AppendLine("}}"); var compilerParams = new CompilerParameters { CompilerOptions = "/target:library /optimize", //编译器选项设置 GenerateInMemory = true, //编译时在内存输出 IncludeDebugInformation = false //生成调试信息 }; //添加相关的引用 compilerParams.ReferencedAssemblies.Add("System.dll"); compilerParams.ReferencedAssemblies.Add("System.Data.dll"); compilerParams.ReferencedAssemblies.Add("System.Xml.dll"); var ass = AppDomain.CurrentDomain.GetAssemblies(); // 得到当前所有程序集 compilerParams.ReferencedAssemblies.Add(ass.FirstOrDefault(o => o.ManifestModule.Name == "Farseer.Net.dll")?.Location); compilerParams.ReferencedAssemblies.Add(ass.FirstOrDefault(o => o.ManifestModule.Name == "Farseer.Net.Sql.dll")?.Location); CompilerResults results = null; try { // 加载成员依赖的类型所在的程序集 var properties = entityType.GetProperties(); foreach (var propertyInfo in properties) { // 找到真实程序集 var declaringType = propertyInfo.PropertyType.GetNullableArguments(); while (declaringType.IsGenericType) { declaringType = declaringType.GetGenericType(); } compilerParams.ReferencedAssemblies.Add(declaringType.Assembly.Location); } // 需要把基类型的dll,也载进来 var baseType = entityType; while (baseType != null) { compilerParams.ReferencedAssemblies.Add(baseType.Assembly.Location); baseType = baseType.BaseType; } var compiler = CodeDomProvider.CreateProvider("CSharp"); //编译 results = compiler.CompileAssemblyFromSource(compilerParams, sb.ToString()); return(results.CompiledAssembly.GetExportedTypes()[0]); } catch (Exception exp) { if (results != null) { var error = new string[results.Errors.Count]; for (int i = 0; i < error.Length; i++) { error[i] = results.Errors[i].ErrorText; LogManger.Log.Error(error[i]); } throw new Exception(error.ToString(",")); } LogManger.Log.Error(exp.ToString()); throw exp; } }