QueryCommonHelper.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341
  1. using Muchinfo.PC.Common.Helpers;
  2. using Muchinfo.MTPClient.Adapter.Utilities;
  3. using Muchinfo.MTPClient.Data;
  4. using Muchinfo.MTPClient.Data.Helper;
  5. using Muchinfo.MTPClient.Data.Model.Account;
  6. using Muchinfo.MTPClient.Infrastructure.LinkProxy;
  7. using Muchinfo.MTPClient.Infrastructure.Utilities;
  8. using Muchinfo.MTPClient.NetworkCore;
  9. using System;
  10. using System.Collections.Generic;
  11. using System.Diagnostics;
  12. using System.IO;
  13. using System.Linq;
  14. using System.Text;
  15. using ProtoBuf;
  16. using tas;
  17. using System.Reflection;
  18. namespace Muchinfo.MTPClient.Service.Utilities
  19. {
  20. /// <summary>
  21. /// 通用查询帮助类
  22. /// </summary>
  23. public class QueryCommonHelper
  24. {
  25. /// <summary>
  26. /// 通用查询方法
  27. /// </summary>
  28. /// <typeparam name="T">泛型,要求是可实例化的对象</typeparam>
  29. /// <param name="statement">查询语句编号</param>
  30. /// <param name="paramValues">查询条件列表,不能转入null</param>
  31. /// <param name="onSuccess">成功回调,将返回查询结果泛型对象列表</param>
  32. /// <param name="onFail">失败回调</param>
  33. /// <param name="requestFunc">The request function.</param>
  34. public static void QueryCommon<T>(string statement, List<QueryCommonParam> paramValues,
  35. Action<List<T>> onSuccess, Action<ErrorEntity> onFail, string requestFunc = null) where T : class, new()
  36. {
  37. QueryCommon<T>(statement, paramValues, new Action<PageInfo<T>>((pageInfo) =>
  38. {
  39. if (null != pageInfo && pageInfo.QueryResults != null)
  40. {
  41. onSuccess(pageInfo.QueryResults);
  42. }
  43. else
  44. {
  45. onSuccess(new List<T>()); ////返回成功,但数据有问题或没有数据。
  46. }
  47. }), onFail, null, requestFunc);
  48. }
  49. /// <summary>
  50. /// 通用查询方法
  51. /// </summary>
  52. /// <typeparam name="T">泛型,要求是可实例化的对象</typeparam>
  53. /// <param name="statement">查询语句编号</param>
  54. /// <param name="paramValues">查询条件列表,不能转入null</param>
  55. /// <param name="onSuccess">成功回调,将返回查询结果泛型对象列表</param>
  56. /// <param name="onFail">失败回调</param>
  57. /// <param name="pageInfo">The page information.</param>
  58. /// <param name="requestFunc">The request function.</param>
  59. public static void QueryCommon<T>(string statement, List<QueryCommonParam> paramValues, Action<PageInfo<T>> onSuccess, Action<ErrorEntity> onFail, PageInfo<object> pageInfo = null, string requestFunc = null) where T : class, new()
  60. {
  61. byte[] reqeust = null;
  62. // 判断当前数据类型,构建用于发送的数据
  63. switch (LinkManager.Instance.Parameters.TradeDatagramType)
  64. {
  65. case Infrastructure.LinkProxy.Enum.DatagramType.Protobuf: // Protobuff
  66. reqeust = BuildRequestWithProtobuf(statement, paramValues, pageInfo);
  67. break;
  68. case Infrastructure.LinkProxy.Enum.DatagramType.Json: // Json
  69. break;
  70. default:
  71. break;
  72. }
  73. if (null == reqeust)
  74. {
  75. if (null != onFail)
  76. onFail(new ErrorEntity() { ReturnCode = -1, ReturnDesc = "通用查询请求错误", RequestFunc = requestFunc }); // 错误数据
  77. return;
  78. }
  79. // 发送数据
  80. var package = new TCPPackage() { Content = reqeust, FunCode = FuncCode.FID_QueryCommonReq };
  81. LinkManager.Instance.TradeTcpLinkProxy.SendPackage(package, new Action<TCPPackage>((responsePackage) =>
  82. {
  83. // 数据发送成功返回
  84. if (null == responsePackage.Content)
  85. if (null != onSuccess)
  86. onSuccess(new PageInfo<T>()); // warning:异常收到空数据内容的包体,目前先直接返回空列表
  87. switch (LinkManager.Instance.Parameters.TradeDatagramType)
  88. {
  89. case Infrastructure.LinkProxy.Enum.DatagramType.Protobuf: // Protobuff
  90. AnalysisResponseWithProtobuf<T>(responsePackage.Content, onSuccess, onFail);
  91. break;
  92. case Infrastructure.LinkProxy.Enum.DatagramType.Json: // Json
  93. break;
  94. default:
  95. break;
  96. }
  97. }), new Action<int, string>((errorCode, errorDesc) =>
  98. {
  99. // 数据发送失败
  100. if (null != onFail)
  101. onFail(new ErrorEntity() { ReturnCode = errorCode, ReturnDesc = errorDesc });
  102. }));
  103. }
  104. /// <summary>
  105. /// 生成Protobuf类型的通用查询请求内容体的方法
  106. /// </summary>
  107. /// <param name="statement">SELECT ID</param>
  108. /// <param name="paramValues">条件对象列表</param>
  109. /// <returns>通用查询请求内容体</returns>
  110. private static byte[] BuildRequestWithProtobuf(string statement, List<QueryCommonParam> paramValues, PageInfo<object> pageInfo = null)
  111. {
  112. // warning: 在这个工程里使用Protobuf需要引用dll,与邓确认此事
  113. var queryCommonReq = new QueryCommonReq();
  114. queryCommonReq.Statement = statement;
  115. if (pageInfo != null)
  116. {
  117. var queryPageInfo = new QueryReqPageInfo();
  118. queryPageInfo.PageNumber = pageInfo.PageNumber;
  119. queryPageInfo.NeedTotalCount = 1;
  120. queryPageInfo.RecordPerPage = pageInfo.RecordPerPage;
  121. // queryPageInfo. = pageInfo.PageNumber;
  122. queryCommonReq.PageInfo = queryPageInfo;
  123. }
  124. foreach (QueryCommonParam param in paramValues)
  125. {
  126. var p = new ParamValue() { Key = param.ParamKey, Value = param.ParamValue };
  127. queryCommonReq.ParamValues.Add(p);
  128. }
  129. return ProtoBufHelper.EntitySerialize(queryCommonReq);
  130. }
  131. /// <summary>
  132. /// 分析通用查询返回数据的方法,采用Protobuf结构体
  133. /// </summary>
  134. /// <typeparam name="T">泛型</typeparam>
  135. /// <param name="content">数据内容</param>
  136. /// <param name="onSuccess">成功回调</param>
  137. /// <param name="onFail">失败回调</param>
  138. private static void AnalysisResponseWithProtobuf<T>(byte[] content, Action<List<T>> onSuccess, Action<ErrorEntity> onFail) where T : class, new()
  139. {
  140. // 获取通用查询返回对象
  141. var queryCommonRsp = ProtoBufHelper.EntityDeSerialize<QueryCommonRsp>(content);
  142. // warning: 这里要处理queryCommonRsp的null异常
  143. if (queryCommonRsp.RetCode == 0)
  144. {
  145. // 操作成功
  146. List<T> returnList = new List<T>();
  147. if (queryCommonRsp.Rsps.Any()) ////可能没有数据
  148. {
  149. returnList = AnalysisPackage<T>(queryCommonRsp);
  150. }
  151. // 调用成功回调
  152. if (null != onSuccess)
  153. onSuccess(returnList);
  154. }
  155. else
  156. {
  157. // 操作失败
  158. if (null != onFail)
  159. {
  160. onFail(new ErrorEntity() { ReturnCode = queryCommonRsp.RetCode, ReturnDesc = queryCommonRsp.RetDesc });
  161. }
  162. }
  163. }
  164. /// <summary>
  165. /// 分析通用查询返回数据的方法,采用Protobuf结构体
  166. /// </summary>
  167. /// <typeparam name="T">泛型</typeparam>
  168. /// <param name="content">数据内容</param>
  169. /// <param name="onSuccess">成功回调</param>
  170. /// <param name="onFail">失败回调</param>
  171. private static void AnalysisResponseWithProtobuf<T>(byte[] content, Action<PageInfo<T>> onSuccess, Action<ErrorEntity> onFail) where T : class, new()
  172. {
  173. // 获取通用查询返回对象
  174. var queryCommonRsp = ProtoBufHelper.EntityDeSerialize<QueryCommonRsp>(content);
  175. // warning: 这里要处理queryCommonRsp的null异常
  176. if (queryCommonRsp.RetCode == 0)
  177. {
  178. PageInfo<T> pageInfo = new PageInfo<T>();
  179. if (queryCommonRsp.PageInfo != null)
  180. {
  181. pageInfo.PageNumber = queryCommonRsp.PageInfo.PageNumber;
  182. pageInfo.TotalCount = queryCommonRsp.PageInfo.TotalCount;
  183. pageInfo.RecordPerPage = queryCommonRsp.PageInfo.RecordPerPage;
  184. }
  185. // 操作成功
  186. List<T> returnList = new List<T>();
  187. if (queryCommonRsp.Rsps.Any()) ////可能没有数据
  188. {
  189. returnList = AnalysisPackage<T>(queryCommonRsp);
  190. #if DEBUG
  191. //获取通用查询返回字段及类型,便于生成对象
  192. var strfff = new StringBuilder();
  193. foreach (var field in queryCommonRsp.Rsps[0].FieldInfos)
  194. {
  195. strfff.Append(string.Format("[PropertyDisc('{1}')] public *{0}* {1} + get; set; -", field.FieldType.ToLower(), field.FieldName.ToLower()));
  196. }
  197. var aaa = strfff.ToString().Replace('+', '{').Replace('-', '}')
  198. .Replace("*bigint*", "long").Replace("*varchar*", "string")
  199. .Replace("*char*", "string").Replace("*decimal*", "decimal")
  200. .Replace("*timestamp*", "DateTime");
  201. Debug.WriteLine(aaa);
  202. #endif
  203. pageInfo.QueryResults = returnList;
  204. }
  205. // 调用成功回调
  206. if (null != onSuccess)
  207. onSuccess(pageInfo);
  208. }
  209. else
  210. {
  211. // 操作失败
  212. if (null != onFail)
  213. {
  214. onFail(new ErrorEntity() { ReturnCode = queryCommonRsp.RetCode, ReturnDesc = queryCommonRsp.RetDesc });
  215. }
  216. }
  217. }
  218. private static List<T> AnalysisPackage<T>(QueryCommonRsp queryCommonRsp) where T : class, new()
  219. {
  220. // 操作成功
  221. List<T> returnList = new List<T>();
  222. // 获取泛型对象所有属性字段
  223. Type type = typeof(T);
  224. List<PropertyInfo> properties = type.GetProperties().Where((item) => item.CanWrite).ToList();
  225. bool isSeted = false;
  226. foreach (RowValue rowValue in queryCommonRsp.Rsps[0].RowValues) // 返回数据行循环
  227. {
  228. T t = new T();
  229. isSeted = false;
  230. foreach (var propertyInfo in properties)
  231. {
  232. var custemAttrs = Attribute.GetCustomAttributes(propertyInfo);
  233. // var custemAttrs = propertyInfo.GetCustomAttributes(typeof(PropertyDiscAttribute),true);
  234. if (null == custemAttrs || !custemAttrs.Any()) ////没有标记的属性不处理
  235. {
  236. continue;
  237. }
  238. var propertyDisc =
  239. custemAttrs.FirstOrDefault((item) => item is PropertyDiscAttribute) as
  240. PropertyDiscAttribute;
  241. if (null == propertyDisc) ////没有标记为反射属性 不进行设置值
  242. {
  243. continue;
  244. }
  245. if (string.IsNullOrEmpty(propertyDisc.PropertyName)) ////无属性名
  246. {
  247. continue;
  248. }
  249. for (int i = 0; i < queryCommonRsp.Rsps[0].FieldInfos.Count; i++)
  250. {
  251. try
  252. {
  253. if (string.IsNullOrWhiteSpace(rowValue.RowValues[i]) || rowValue.RowValues[i].ToLower().Equals("null"))
  254. {
  255. continue;
  256. }
  257. tas.FieldInfo fieldInfo = queryCommonRsp.Rsps[0].FieldInfos[i];
  258. // 查找泛型对象中相同的属性名称
  259. if (propertyDisc.PropertyName.Trim().ToLower().Equals(fieldInfo.FieldName.Trim().ToLower()))
  260. {
  261. isSeted = true;
  262. // 判断类型赋值
  263. if (propertyInfo.PropertyType == typeof(String))
  264. {
  265. propertyInfo.SetValue(t, rowValue.RowValues[i], null);
  266. }
  267. else if (propertyInfo.PropertyType == typeof(Int32) || propertyInfo.PropertyType == typeof(int))
  268. {
  269. propertyInfo.SetValue(t, Convert.ToInt32(rowValue.RowValues[i]), null);
  270. }
  271. else if (propertyInfo.PropertyType == typeof(UInt32) || propertyInfo.PropertyType == typeof(int))
  272. {
  273. propertyInfo.SetValue(t, Convert.ToUInt32(rowValue.RowValues[i]), null);
  274. }
  275. else if (propertyInfo.PropertyType == typeof(DateTime))
  276. {
  277. DateTime date;
  278. if (DateTime.TryParse(rowValue.RowValues[i], out date))
  279. {
  280. propertyInfo.SetValue(t, date, null);
  281. }
  282. }
  283. else if (propertyInfo.PropertyType == typeof(Decimal))
  284. {
  285. propertyInfo.SetValue(t, Convert.ToDecimal(rowValue.RowValues[i]), null);
  286. }
  287. else if (propertyInfo.PropertyType == typeof(Double))
  288. {
  289. propertyInfo.SetValue(t, Convert.ToDouble(rowValue.RowValues[i]), null);
  290. }
  291. else if (propertyInfo.PropertyType == typeof(Boolean))
  292. {
  293. propertyInfo.SetValue(t, Convert.ToBoolean(rowValue.RowValues[i]), null);
  294. }
  295. else if (propertyInfo.PropertyType == typeof(long) || propertyInfo.PropertyType == typeof(Int64))
  296. {
  297. propertyInfo.SetValue(t, Convert.ToInt64(rowValue.RowValues[i]), null);
  298. }
  299. else if (propertyInfo.PropertyType == typeof(ulong) || propertyInfo.PropertyType == typeof(UInt64))
  300. {
  301. propertyInfo.SetValue(t, Convert.ToUInt64(rowValue.RowValues[i]), null);
  302. }
  303. else if (propertyInfo.PropertyType.IsValueType)
  304. {
  305. propertyInfo.SetValue(t, Convert.ToInt32(rowValue.RowValues[i]), null);
  306. }
  307. }
  308. }
  309. catch (Exception ex)
  310. {
  311. LogHelper.WriteError(typeof(QueryCommonHelper), propertyDisc.PropertyName + " value: " + rowValue.RowValues[i] + " ex:" + ex.ToString());
  312. }
  313. }
  314. }
  315. if (isSeted)
  316. returnList.Add(t);
  317. }
  318. return returnList;
  319. }
  320. }
  321. }