个人觉得轻简级的ORM既要支持强类型编码,又要有执行效率,还要通俗易懂给开发者友好提示,结合Expression可轻松定制自己所需要功能。

Orm成品开源项目地址
https://github.com/PlugNT/util6

表达式解析类:

  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Data.Common;
  5. using System.Linq;
  6. using System.Linq.Expressions;
  7. using System.Text;
  8. using System.Reflection;
  9. using System.Text.RegularExpressions;
  10.  
  11. using Util.Database;
  12. namespace Util.EntityMapping
  13. {
  14.  
  15. public class SqlLmdResolver
  16. {
  17.  
  18. internal int ParaIndex = ;
  19.  
  20. public string _SqlWhere = null;
  21. public string SqlWhere
  22. {
  23. get { return _SqlWhere; }
  24. }
  25.  
  26. private List<DbParameter> _Parameters = null;
  27. public List<DbParameter> Parameters
  28. {
  29. get { return _Parameters; }
  30. }
  31.  
  32. private DbConfig _DbConfig = null;
  33.  
  34. public SqlLmdResolver(DbConfig config = null)
  35. {
  36. _DbConfig = config ?? DbConfig.Default;
  37. _SqlWhere = string.Empty;
  38. _Parameters = new List<DbParameter>();
  39. }
  40.  
  41. public void ResolveExpression(Expression expression = null, SqlWhereType whereType = SqlWhereType.And)
  42. {
  43. if (expression == null)
  44. {
  45. _SqlWhere = string.Empty;
  46. return;
  47. }
  48. var sqlFormat = (whereType == SqlWhereType.And) ? " AND {0} " : " OR {0} ";
  49. SqlLmdResolver.MemberType type = SqlLmdResolver.MemberType.None;
  50. this._SqlWhere = string.Format(sqlFormat, GetResolveAll(expression, ref type).SqlConditions);
  51. }
  52.  
  53. private enum MemberType
  54. {
  55. None = ,
  56. Left = ,
  57. Right =
  58. }
  59.  
  60. private struct ParamInfo
  61. {
  62. public string SqlConditions;
  63. public object ObjectValue;
  64. }
  65.  
  66. private string AddParametersReturnLeft(ref ParamInfo left, ParamInfo right)
  67. {
  68. string oldLeftKey = left.SqlConditions;
  69. left.SqlConditions = "P"+ ParaIndex + oldLeftKey;
  70. ParaIndex++;
  71. if (right.ObjectValue == null)
  72. {
  73. this._Parameters.Add(DbProvider.MakeParam(_DbConfig, "@" + left.SqlConditions, DBNull.Value));
  74. }
  75. else
  76. {
  77. this._Parameters.Add(DbProvider.MakeParam(_DbConfig, "@" + left.SqlConditions, right.ObjectValue));
  78. }
  79. return oldLeftKey;
  80. }
  81. private string AddParametersReturnRight(ParamInfo left, ref ParamInfo right)
  82. {
  83. string oldRightKey = right.SqlConditions;
  84. right.SqlConditions = "P" + ParaIndex + oldRightKey;
  85. ParaIndex++;
  86. if (left.ObjectValue == null)
  87. {
  88. this._Parameters.Add(DbProvider.MakeParam(_DbConfig, "@" + right.SqlConditions, DBNull.Value));
  89. }
  90. else
  91. {
  92. this._Parameters.Add(DbProvider.MakeParam(_DbConfig, "@" + right.SqlConditions, left.ObjectValue));
  93. }
  94. return oldRightKey;
  95. }
  96.  
  97. private string GetOperator(ExpressionType expressiontype)
  98. {
  99. switch (expressiontype)
  100. {
  101. case ExpressionType.And:
  102. case ExpressionType.AndAlso:
  103. return " AND ";
  104. case ExpressionType.Equal:
  105. return " =";
  106. case ExpressionType.GreaterThan:
  107. return " >";
  108. case ExpressionType.GreaterThanOrEqual:
  109. return ">=";
  110. case ExpressionType.LessThan:
  111. return "<";
  112. case ExpressionType.LessThanOrEqual:
  113. return "<=";
  114. case ExpressionType.NotEqual:
  115. return "<>";
  116. case ExpressionType.Or:
  117. case ExpressionType.OrElse:
  118. return " OR ";
  119. case ExpressionType.Add:
  120. case ExpressionType.AddChecked:
  121. return "+";
  122. case ExpressionType.Subtract:
  123. case ExpressionType.SubtractChecked:
  124. return "-";
  125. case ExpressionType.Divide:
  126. return "/";
  127. case ExpressionType.Multiply:
  128. case ExpressionType.MultiplyChecked:
  129. return "*";
  130. default:
  131. throw new Exception(string.Format("不支持{0}此种运算符查找!", expressiontype.ToString()));
  132. }
  133. }
  134.  
  135. private ParamInfo GetResolveAll(Expression exp, ref MemberType type, bool isTure = true)
  136. {
  137. if (exp is LambdaExpression)
  138. {
  139. return GetResolveLambda(exp);
  140. }
  141. else if (exp is BinaryExpression)
  142. {
  143. return GetResolveBinary(exp);
  144. }
  145. else if (exp is MethodCallExpression)
  146. {
  147. return GetResolveMethodCall(exp, ref type, isTure);
  148. }
  149. else if (exp is ConstantExpression)
  150. {
  151. return GetResolveConstant(exp, ref type);
  152. }
  153. else if (exp is MemberExpression)
  154. {
  155. return GetResolveMember(exp, ref type);
  156. }
  157. else if (exp is UnaryExpression)
  158. {
  159. return GetResolveUnary(exp, ref type);
  160. }
  161. return new ParamInfo();
  162. }
  163.  
  164. private ParamInfo GetResolveLambda(Expression exp)
  165. {
  166. LambdaExpression lambda = exp as LambdaExpression;
  167. var expression = lambda.Body;
  168. MemberType EleType = MemberType.None;
  169.  
  170. if (expression is UnaryExpression)
  171. {
  172. var me = expression as UnaryExpression;
  173. if (me.Operand is MemberExpression)
  174. {
  175. var ime = me.Operand as MemberExpression;
  176. return new ParamInfo { SqlConditions = ime.Member.Name.ToString() + "=0" };
  177. }
  178. }
  179. if (expression is MemberExpression)
  180. {
  181. var me = expression as MemberExpression;
  182. return new ParamInfo { SqlConditions = me.Member.Name.ToString() + "=1" };
  183. }
  184. return GetResolveAll(expression, ref EleType);
  185. }
  186. private ParamInfo GetResolveBinary(Expression exp)
  187. {
  188. var expression = exp as BinaryExpression;
  189. MemberType leftType = MemberType.None;
  190. MemberType rightType = MemberType.None;
  191.  
  192. var left = GetResolveAll(expression.Left, ref leftType);
  193. var right = GetResolveAll(expression.Right, ref rightType);
  194. var oper = GetOperator(expression.NodeType);
  195. var isKeyOperValue = leftType == MemberType.Left && rightType == MemberType.Right;
  196. var isValueOperKey = rightType == MemberType.Left && leftType == MemberType.Right;
  197.  
  198. if (leftType == MemberType.Left && rightType == MemberType.None)
  199. {
  200. if (expression.Left is UnaryExpression)
  201. {
  202. var me = expression.Left as UnaryExpression;
  203. if (me.Operand is MemberExpression)
  204. {
  205. left.SqlConditions = left.SqlConditions + "=0";
  206. }
  207. }
  208. else if (expression.Left is MemberExpression)
  209. {
  210. left.SqlConditions = left.SqlConditions + "=1";
  211. }
  212. }
  213. if (leftType == MemberType.None && rightType == MemberType.Left)
  214. {
  215. if (expression.Right is UnaryExpression)
  216. {
  217. var me = expression.Right as UnaryExpression;
  218. if (me.Operand is MemberExpression)
  219. {
  220. right.SqlConditions = right.SqlConditions + "=0";
  221. }
  222. }
  223. else if (expression.Right is MemberExpression)
  224. {
  225. right.SqlConditions = right.SqlConditions + "=1";
  226. }
  227. }
  228.  
  229. if (isKeyOperValue & (right.ObjectValue == null) && oper.Trim() == "=")
  230. {
  231. var oldLeft = AddParametersReturnLeft(ref left, right);
  232. return new ParamInfo { SqlConditions = string.Format(" ({0} is null) ", oldLeft) };
  233. }
  234. else if (isKeyOperValue & (right.ObjectValue == null) && oper.Trim() == "<>")
  235. {
  236. var oldLeft = AddParametersReturnLeft(ref left, right);
  237. return new ParamInfo { SqlConditions = string.Format(" ({0} is not null) ", oldLeft) };
  238. }
  239. else if (isValueOperKey & (left.ObjectValue == null) && oper.Trim() == "=")
  240. {
  241. return new ParamInfo { SqlConditions = string.Format(" ({0} is null) ", right.SqlConditions) };
  242. }
  243. else if (isValueOperKey & (left.ObjectValue == null) && oper.Trim() == "<>")
  244. {
  245. return new ParamInfo { SqlConditions = string.Format(" ({0} is not null) ", right.SqlConditions) };
  246. }
  247.  
  248. else if (isKeyOperValue)
  249. {
  250. var oldLeft = AddParametersReturnLeft(ref left, right);
  251. return new ParamInfo { SqlConditions = string.Format(" ({0} {1} @{2}) ", oldLeft, oper, left.SqlConditions) };
  252. }
  253. else if (isValueOperKey)
  254. {
  255. var oldRight = AddParametersReturnRight(left, ref right);
  256. return new ParamInfo { SqlConditions = string.Format(" (@{0} {1} {2}) ", right.SqlConditions, oper, oldRight) };
  257. }
  258. else if (leftType == MemberType.Right && rightType == MemberType.Right)
  259. {
  260. return new ParamInfo { SqlConditions = string.Format(" ('{0}' {1} '{2}') ", left.SqlConditions, oper, right.SqlConditions) };
  261. }
  262. else
  263. {
  264. return new ParamInfo { SqlConditions = string.Format(" ({0} {1} {2}) ", left.SqlConditions, oper, right.SqlConditions) };
  265. }
  266. }
  267. private ParamInfo GetResolveMethodCall(Expression exp, ref MemberType type, bool isTure)
  268. {
  269. MethodCallExpression mce = (MethodCallExpression)exp;
  270. string methodName = mce.Method.Name;
  271. if (methodName == "Contains")
  272. {
  273. MemberType leftType = MemberType.None;
  274. MemberType rightType = MemberType.None;
  275. if (mce.Method.DeclaringType != typeof(string) && mce.Method.DeclaringType.GetInterface("IEnumerable") != null)
  276. {
  277. var left = GetResolveAll(mce.Arguments[], ref rightType);
  278. var right = GetResolveAll(mce.Object, ref leftType);
  279. string oldLeftKey = left.SqlConditions;
  280.  
  281. string leftKey = "P" + ParaIndex + left.SqlConditions;
  282. ParaIndex++;
  283. var sqlParameterNames = "";
  284. var memberType = MemberType.Right;
  285. var list = GetResolveMember(mce.Object as MemberExpression, ref memberType).ObjectValue as IEnumerable;
  286. var count = ;
  287. foreach (var item in list)
  288. {
  289. var parameterName = leftKey + count;
  290. sqlParameterNames += ",@" + parameterName;
  291. if (item == null)
  292. {
  293. this._Parameters.Add(DbProvider.MakeParam(_DbConfig, "@" + parameterName, DBNull.Value));
  294. }
  295. else
  296. {
  297. this._Parameters.Add(DbProvider.MakeParam(_DbConfig, "@" + parameterName, item));
  298. }
  299. count++;
  300. }
  301. sqlParameterNames = sqlParameterNames.TrimStart(',');
  302. return new ParamInfo { SqlConditions = string.Format("({0} {1} IN ({2}))", oldLeftKey, isTure == false ? " NOT " : "", sqlParameterNames) };
  303. }
  304. else
  305. {
  306. var left = GetResolveAll(mce.Object, ref leftType);
  307. var right = GetResolveAll(mce.Arguments[], ref rightType);
  308. var oldLeft = AddParametersReturnLeft(ref left, right);
  309. return new ParamInfo { SqlConditions = string.Format("({0} {1} LIKE '%'+@{2}+'%')", oldLeft, isTure == false ? " NOT " : "", left.SqlConditions) };
  310. }
  311. }
  312. else if (methodName == "StartsWith")
  313. {
  314. MemberType leftType = MemberType.None;
  315. MemberType rightType = MemberType.None;
  316. var left = GetResolveAll(mce.Object, ref leftType);
  317. var right = GetResolveAll(mce.Arguments[], ref rightType);
  318. var oldLeft = AddParametersReturnLeft(ref left, right);
  319. return new ParamInfo { SqlConditions = string.Format("({0} {1} LIKE @{2}+'%')", oldLeft, isTure == false ? " NOT " : "", left.SqlConditions) };
  320. }
  321. else if (methodName == "EndWith")
  322. {
  323. MemberType leftType = MemberType.None;
  324. MemberType rightType = MemberType.None;
  325. var left = GetResolveAll(mce.Object, ref leftType);
  326. var right = GetResolveAll(mce.Arguments[], ref rightType);
  327. var oldLeft = AddParametersReturnLeft(ref left, right);
  328. return new ParamInfo { SqlConditions = string.Format("({0} {1} LIKE '%'+@{2})", oldLeft, isTure == false ? " NOT " : "", left.SqlConditions) };
  329. }
  330. else if (methodName == "ToString")
  331. {
  332. type = MemberType.Right;
  333. return GetResolveAll(mce.Object, ref type);
  334. }
  335. else if (methodName.StartsWith("To"))
  336. {
  337. type = MemberType.Right;
  338. return GetResolveAll(mce.Arguments[], ref type);
  339. }
  340. return new ParamInfo();
  341. }
  342.  
  343. private ParamInfo GetResolveConstant(Expression exp, ref MemberType type)
  344. {
  345. type = MemberType.Right;
  346. ConstantExpression ce = ((ConstantExpression)exp);
  347. if (ce.Value == null)
  348. {
  349. return new ParamInfo();
  350. }
  351. else
  352. {
  353. return new ParamInfo { ObjectValue = ce.Value };
  354. }
  355. }
  356. private ParamInfo GetResolveUnary(Expression exp, ref MemberType type)
  357. {
  358. UnaryExpression ue = ((UnaryExpression)exp);
  359. var mex = ue.Operand;
  360. return GetResolveAll(mex, ref type, false);
  361. }
  362.  
  363. private ParamInfo GetResolveMemberMethod(MemberExpression exp)
  364. {
  365. var proInfo = exp.Member as System.Reflection.PropertyInfo;
  366. if (proInfo != null)
  367. {
  368. object dynInv = proInfo.GetValue(null, null);
  369. return new ParamInfo { ObjectValue = dynInv };
  370. }
  371. else
  372. {
  373. var fieInfo = exp.Member as System.Reflection.FieldInfo;
  374. if (fieInfo != null)
  375. {
  376. object dynInv = fieInfo.GetValue(null);
  377. return new ParamInfo { ObjectValue = dynInv };
  378. }
  379. }
  380. return new ParamInfo();
  381. }
  382. private ParamInfo GetResolveMemberConstant(MemberExpression exp, object obj)
  383. {
  384. var proInfo = exp.Member as System.Reflection.PropertyInfo;
  385. if (proInfo != null)
  386. {
  387. var dynInv = proInfo.GetValue(obj, null);
  388. return new ParamInfo { ObjectValue = dynInv };
  389. }
  390. else
  391. {
  392. var fieInfo = exp.Member as System.Reflection.FieldInfo;
  393. if (fieInfo != null)
  394. {
  395. var dynInv = fieInfo.GetValue(obj);
  396. return new ParamInfo { ObjectValue = dynInv };
  397. }
  398. }
  399. return new ParamInfo();
  400. }
  401. private ParamInfo GetResolveMember(Expression exp, ref MemberType type)
  402. {
  403. MemberExpression me = ((MemberExpression)exp);
  404. if (me.Expression == null)
  405. {
  406. type = MemberType.Right;
  407. return GetResolveMemberMethod(me);
  408. }
  409.  
  410. if (me.Expression.NodeType != ExpressionType.Parameter)
  411. {
  412. type = MemberType.Right;
  413. object dynInv = null;
  414. try
  415. {
  416. var conExp = me.Expression as ConstantExpression;
  417. if (conExp != null)
  418. {
  419. return GetResolveMemberConstant(me, conExp.Value);
  420. }
  421. else
  422. {
  423. var memberInfos = new Stack<MemberInfo>();
  424. while (exp is MemberExpression)
  425. {
  426. var memberExpr = exp as MemberExpression;
  427. memberInfos.Push(memberExpr.Member);
  428. exp = memberExpr.Expression;
  429. }
  430.  
  431. var constExpr = exp as ConstantExpression;
  432. if (constExpr == null)
  433. {
  434. var member = exp as MemberExpression;
  435. if (member == null)
  436. {
  437. throw new Exception("不支持的子表达式" + me.Member.Name);
  438. }
  439. return GetResolveMemberMethod(member);
  440. }
  441. var objReference = constExpr.Value;
  442.  
  443. while (memberInfos.Count > )
  444. {
  445. var mi = memberInfos.Pop();
  446. if (mi.MemberType == MemberTypes.Property)
  447. {
  448. objReference = objReference.GetType().GetProperty(mi.Name).GetValue(objReference, null);
  449. }
  450. else if (mi.MemberType == MemberTypes.Field)
  451. {
  452. objReference = objReference.GetType().GetField(mi.Name).GetValue(objReference);
  453. }
  454. }
  455. dynInv = objReference;
  456. }
  457. }
  458. catch (Exception ex)
  459. {
  460. throw new Exception("表达式解析出错(" + me.NodeType.ToString() + "):" + ex.Message);
  461. }
  462.  
  463. if (dynInv == null)
  464. {
  465. return new ParamInfo();
  466. }
  467. else
  468. {
  469. return new ParamInfo { ObjectValue = dynInv };
  470. }
  471. }
  472. else
  473. {
  474. string name = me.Member.Name;
  475. type = MemberType.Left;
  476. return new ParamInfo { SqlConditions = name };
  477. }
  478. }
  479.  
  480. }
  481.  
  482. }

测试代码如下:

  1. [TestMethod]
  2. public void TestSqlLmdResolve()
  3. {
  4. //ORM数据映射
  5. DbConfig.UseDefaultConfig(new TModelDbConfig(GetDbPath()));
  6.  
  7. var where = GetSqlWhere<cms_category>(m => m.enabled && m.name == "test");
  8. Console.WriteLine("LmdSql1:" + where);
  9. where = GetSqlWhere<cms_category>(m => !m.enabled && m.name.Contains("test") && m.enabled);
  10. Console.WriteLine("LmdSql2:" + where);
  11.  
  12. //条件优先级
  13. where = GetSqlWhere<cms_category>(m => (!m.enabled && m.name.Contains("test") && m.enabled) || m.name.StartsWith("test"));
  14. Console.WriteLine("LmdSql3:" + where);
  15. where = GetSqlWhere<cms_category>(m => (m.enabled && m.name.Contains("test") && m.enabled) || (m.name.StartsWith("test") && !m.isused && m.isused));
  16.  
  17. //其他判断
  18. Console.WriteLine("LmdSql4:" + where);
  19. where = GetSqlWhere<cms_category>(m => !m.enabled && m.name.Contains("test") && !m.enabled);
  20. Console.WriteLine("LmdSql5:" + where);
  21. where = GetSqlWhere<cms_category>(m => !m.enabled && m.name.Contains("test") && m.enabled == true);
  22. Console.WriteLine("LmdSql6:" + where);
  23. where = GetSqlWhere<cms_category>(m => m.name.Contains("test") && m.enabled || m.name.StartsWith("test"));
  24. Console.WriteLine("LmdSql7:" + where);
  25. where = GetSqlWhere<cms_category>(m => m.enabled);
  26. Console.WriteLine("LmdSql8:" + where);
  27. where = GetSqlWhere<cms_category>(m => !m.enabled);
  28. Console.WriteLine("LmdSql9:" + where);
  29. where = GetSqlWhere<cms_category>(m => m.name.StartsWith("test"));
  30. Console.WriteLine("LmdSql10:" + where);
  31. where = GetSqlWhere<cms_category>(m => !m.name.StartsWith("test"));
  32. Console.WriteLine("LmdSql11:" + where);
  33. where = GetSqlWhere<cms_category>(m => m.name.StartsWith("test") || m.name.Contains("test"));
  34. Console.WriteLine("LmdSql12:" + where);
  35.  
  36. //条件判断是否前包含,判断常量相等,多层判断
  37. var extend = new cms_category_extend();
  38. extend.mytest2 = new cms_category_extend();
  39. extend.mytest2.mytest1 = new cms_category { name = "hehhe" };
  40. where = GetSqlWhere<cms_category>(m => m.name.StartsWith("test") || m.name == cms_category.TestConst ||
  41. m.name == extend.mytest2.mytest1.name);
  42. Console.WriteLine("LmdSql13:" + where);
  43.  
  44. //判断列表包含
  45. var list = new List<string> { "a", "b", "c" };
  46. where = GetSqlWhere<cms_category>(m => list.Contains(m.name));
  47. Console.WriteLine("LmdSql14:" + where);
  48.  
  49. object testName = "test";
  50. where = GetSqlWhere<cms_category>(m => m.enabled && m.name == (string)testName);
  51. Console.WriteLine("LmdSql15:" + where);
  52. object testParent_id = ;
  53. //枚举判断
  54. where = GetSqlWhere<cms_category>(m => (m.id == (int)testParent_id) || (m.enabled && m.parent_id == Status.Success));
  55. Console.WriteLine("LmdSql16:" + where);
  56.  
  57. //静态字段判断
  58. where = GetSqlWhere<cms_category>(m => m.name == cms_category.TestStatic);
  59. Console.WriteLine("LmdSql17:" + where);
  60. }
  61.  
  62. private string GetSqlWhere<T>(Expression<Func<T, bool>> expression)
  63. {
  64. SqlLmdResolver exp = new SqlLmdResolver();
  65. exp.ResolveExpression(expression);
  66. return exp.SqlWhere + "\r\n" + string.Join(",", exp.Parameters.Select(m => m.ParameterName + ":" + m.Value.ToString()));
  67. }

成品测试如下:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.Concurrent;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Data;
  7. using System.Data.Common;
  8. using Microsoft.VisualStudio.TestTools.UnitTesting;
  9.  
  10. using Util.Database;
  11. using Util.EntityMapping;
  12. using System.Linq.Expressions;
  13. namespace Util.UnitTest
  14. {
  15. [TestClass]
  16. public class TestDatabase_Unit
  17. {
  18.  
  19. #region lmd生成sql条件测试
  20.  
  21. [TestMethod]
  22. public void TestSqlLmdResolve()
  23. {
  24. //ORM数据映射
  25. DbConfig.UseDefaultConfig(new TModelDbConfig(GetDbPath()));
  26.  
  27. var where = GetSqlWhere<cms_category>(m => m.enabled && m.name == "test");
  28. Console.WriteLine("LmdSql1:" + where);
  29. where = GetSqlWhere<cms_category>(m => !m.enabled && m.name.Contains("test") && m.enabled);
  30. Console.WriteLine("LmdSql2:" + where);
  31.  
  32. //条件优先级
  33. where = GetSqlWhere<cms_category>(m => (!m.enabled && m.name.Contains("test") && m.enabled) || m.name.StartsWith("test"));
  34. Console.WriteLine("LmdSql3:" + where);
  35. where = GetSqlWhere<cms_category>(m => (m.enabled && m.name.Contains("test") && m.enabled) || (m.name.StartsWith("test") && !m.isused && m.isused));
  36.  
  37. //其他判断
  38. Console.WriteLine("LmdSql4:" + where);
  39. where = GetSqlWhere<cms_category>(m => !m.enabled && m.name.Contains("test") && !m.enabled);
  40. Console.WriteLine("LmdSql5:" + where);
  41. where = GetSqlWhere<cms_category>(m => !m.enabled && m.name.Contains("test") && m.enabled == true);
  42. Console.WriteLine("LmdSql6:" + where);
  43. where = GetSqlWhere<cms_category>(m => m.name.Contains("test") && m.enabled || m.name.StartsWith("test"));
  44. Console.WriteLine("LmdSql7:" + where);
  45. where = GetSqlWhere<cms_category>(m => m.enabled);
  46. Console.WriteLine("LmdSql8:" + where);
  47. where = GetSqlWhere<cms_category>(m => !m.enabled);
  48. Console.WriteLine("LmdSql9:" + where);
  49. where = GetSqlWhere<cms_category>(m => m.name.StartsWith("test"));
  50. Console.WriteLine("LmdSql10:" + where);
  51. where = GetSqlWhere<cms_category>(m => !m.name.StartsWith("test"));
  52. Console.WriteLine("LmdSql11:" + where);
  53. where = GetSqlWhere<cms_category>(m => m.name.StartsWith("test") || m.name.Contains("test"));
  54. Console.WriteLine("LmdSql12:" + where);
  55.  
  56. //条件判断是否前包含,判断常量相等,多层判断
  57. var extend = new cms_category_extend();
  58. extend.mytest2 = new cms_category_extend();
  59. extend.mytest2.mytest1 = new cms_category { name = "hehhe" };
  60. where = GetSqlWhere<cms_category>(m => m.name.StartsWith("test") || m.name == cms_category.TestConst ||
  61. m.name == extend.mytest2.mytest1.name);
  62. Console.WriteLine("LmdSql13:" + where);
  63.  
  64. //判断列表包含
  65. var list = new List<string> { "a", "b", "c" };
  66. where = GetSqlWhere<cms_category>(m => list.Contains(m.name));
  67. Console.WriteLine("LmdSql14:" + where);
  68.  
  69. object testName = "test";
  70. where = GetSqlWhere<cms_category>(m => m.enabled && m.name == (string)testName);
  71. Console.WriteLine("LmdSql15:" + where);
  72. object testParent_id = ;
  73. //枚举判断
  74. where = GetSqlWhere<cms_category>(m => (m.id == (int)testParent_id) || (m.enabled && m.parent_id == Status.Success));
  75. Console.WriteLine("LmdSql16:" + where);
  76.  
  77. //静态字段判断
  78. where = GetSqlWhere<cms_category>(m => m.name == cms_category.TestStatic);
  79. Console.WriteLine("LmdSql17:" + where);
  80. }
  81.  
  82. private string GetSqlWhere<T>(Expression<Func<T, bool>> expression)
  83. {
  84. SqlLmdResolver exp = new SqlLmdResolver();
  85. exp.ResolveExpression(expression);
  86. return exp.SqlWhere + "\r\n" + string.Join(",", exp.Parameters.Select(m => m.ParameterName + ":" + m.Value.ToString()));
  87. }
  88.  
  89. #endregion
  90.  
  91. #region access orm测试
  92.  
  93. private string GetDbPath()
  94. {
  95. var path = AppDomain.CurrentDomain.BaseDirectory;
  96. if (path.EndsWith("debug", StringComparison.OrdinalIgnoreCase))
  97. {
  98. path = path.Substring(, path.LastIndexOf('\\'));
  99. path = path.Substring(, path.LastIndexOf('\\'));
  100. path = path.Substring(, path.LastIndexOf('\\'));
  101. }
  102. path = path.TrimEnd('\\') + @"\DataBase";
  103. return path;
  104. }
  105. [TestMethod]
  106. public void TestDbConfig()
  107. {
  108. //初始化配置
  109. DbConfig.UseDefaultConfig(new TModelDbConfig(GetDbPath()));
  110.  
  111. //T4模版获取数据库信息
  112. List<TableInfo> list = DbFactory.GetShemaTables();
  113. Console.WriteLine(list.Count.ToString());
  114. }
  115.  
  116. [TestMethod]
  117. public void TestAccessOrm()
  118. {
  119.  
  120. //ORM数据映射
  121. DbConfig.UseDefaultConfig(new TModelDbConfig(GetDbPath()));
  122. Console.WriteLine("Start loadding...");
  123. Console.WriteLine(new cms_category().Query(m => m.name == "城市").ToCount());
  124. var cat = new cms_category().Query(m => m.name == "城市").SortAsc(m => m.name).ToModel();
  125. Console.WriteLine(cat.name);
  126.  
  127. //设置只更新部分
  128. //cat.SetPartHandled();
  129. //cat.description = "test";
  130. //cat.Update(m=>m.id == 1);
  131.  
  132. Console.WriteLine(cat.ToValue(m => m.name));
  133. Console.WriteLine(new cms_category().Query(m => m.name == "城市").ToList()[].name);
  134. Console.WriteLine(new cms_category().Query(m => m.name == "城市" && m.id > && m.name == "" || (m.id == || m.name == "")).ToCount());
  135. //指定条件规则查询
  136. Console.WriteLine(new cms_category().Query(m => (m.name == "城市" && (m.id > || m.name == "")) || (m.id == || m.name == "")).ToCount());
  137.  
  138. var cityList = new List<string> { "城市", "b", "c" };
  139. var layer = new LayerModel { List = cityList };
  140. Console.WriteLine(new cms_category().Query(m => m.name == "城市" || cityList.Contains(m.name) || m.parent_id == Status.Success).ToCount());
  141. Console.WriteLine(new cms_category().Query(m => m.name == "城市" || layer.List.Contains(m.name)).ToCount());
  142.  
  143. //获取全部
  144. var datsList = new cms_category().Query().ToList();
  145. Console.WriteLine(datsList.Count);
  146. //获取N条
  147. datsList = new cms_category().Query().ToList();
  148. Console.WriteLine(datsList.Count);
  149. //获取部分
  150. var partList = new cms_category().Query().ToPartList(, "id", "name").Select(m => new cms_category
  151. {
  152. id = int.Parse(m[]),
  153. name = m[]
  154. }).ToList();
  155. Console.WriteLine(partList.Count);
  156. //分页查询
  157. var mapper = new cms_category().Query();
  158. var dataCount = mapper.ToCount();
  159. datsList = mapper.ToList(, , dataCount);
  160. Console.WriteLine(datsList.Count);
  161. //条件拼接查询
  162. mapper.And(m => m.name == "test")
  163. .And(m => m.id > )
  164. .Or(m => m.parent_id > );
  165. mapper.Or(m => m.parent_id > );
  166.  
  167. var channels = new cms_channel().Query().ToList();
  168. Console.WriteLine(channels.Count);
  169. var grade = new ucl_grade { id = };
  170. grade.grade_name = "新手1";
  171. var dal = new UclGradeDataAccess(grade);
  172. //保持数据库连接
  173. using (var db = new DbBuilder(new TModelDbConfig(GetDbPath())).KeepConnect())
  174. {
  175. //使用数据库db操作并跟踪实体修改状态
  176. dal.UseDatabase(db).SetPartHandled();
  177. grade.grade = ;
  178. grade.grade_name = "新手";
  179. dal.Update();
  180. }
  181. //db销毁后重连数据库
  182. Console.WriteLine(dal.ToValue(m => m.grade_name));
  183.  
  184. //使用事务(在事务中处理)
  185. using (var db = new DbBuilder(new TModelDbConfig(GetDbPath())).KeepConnect())
  186. {
  187. try
  188. {
  189. db.BeginTransaction();
  190. //TODO:something
  191. //使用数据库db操作并跟踪实体修改状态
  192. dal.UseDatabase(db).SetPartHandled();
  193. grade.grade = ;
  194. grade.grade_name = "新手";
  195. dal.Update();
  196. db.CommitTransaction();
  197. }
  198. catch (Exception ex)
  199. {
  200. db.RollbackTransaction();
  201. }
  202. }
  203.  
  204. //使用事务(批处理事务)
  205. var parList = new List<DbParamInfo>();
  206. //添加到批处理事务中,如果执行失败则回滚事务
  207. parList.Add(dal.GetUpdateDbParamInfo().UseVerifyExecResult());
  208. //TODO:添加其他操作到parList
  209. var execCount = new DbBuilder(new TModelDbConfig(GetDbPath())).ExecuteSqlTran(parList);
  210. Console.WriteLine(execCount);
  211. }
  212.  
  213. [TestMethod]
  214. public void TestMappingField()
  215. {
  216. var cat = new cms_category();
  217. var watch = System.Diagnostics.Stopwatch.StartNew();
  218. var eachCount = ;
  219. for (var i = ; i < eachCount; i++)
  220. {
  221. var field = new cms_category().ExpField(f => f.name);
  222. }
  223. watch.Stop();
  224. Console.WriteLine("Linq反射取" + eachCount + "次字段毫秒数:" + watch.ElapsedMilliseconds);
  225. }
  226.  
  227. //===============================================================================================
  228. //access 测试配置类
  229. //===============================================================================================
  230. public class TModelDbConfig : DbConfig
  231. {
  232. public static void DBWriteLogInfo(string info, string title, string logpath, string encoding)
  233. {
  234. Console.WriteLine("dblog:" + info);
  235. }
  236. public TModelDbConfig(string solutionDir) : base("System.Data.OleDb",
  237. @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + solutionDir + @"\PlugNT_CMS.mdb;User ID=;Password=;",
  238. DBWriteLogInfo)
  239. { }
  240.  
  241. }
  242.  
  243. [Table("cms_channel")]
  244. public partial class cms_channel : BaseMapper<cms_channel>
  245. {
  246. public int id { get; set; }
  247. public string no { get; set; }
  248. public string title { get; set; }
  249. }
  250. public class LayerModel
  251. {
  252. public List<string> List { get; set; }
  253. }
  254. public partial class cms_category : BaseMapper<cms_category>
  255. {
  256.  
  257. public static string TestStatic = "TestStatic";
  258. public const string TestConst = "TestConst";
  259.  
  260. public int id { get; set; }
  261. public string name { get; set; }
  262. //public int parent_id { get; set; }
  263. public Status parent_id { get; set; }
  264.  
  265. [Obsolete("test")]
  266. public bool enabled { get; set; }
  267. [Obsolete("test")]
  268. public bool isused { get; set; }
  269.  
  270. public override string TableName
  271. {
  272. get { return "cms_category"; }
  273. }
  274. protected override cms_category ConvertEntity(IDataReader reader)
  275. {
  276. return new cms_category
  277. {
  278. id = int.Parse(reader["id"].ToString()),
  279. name = reader["name"].ToString(),
  280. parent_id = (Status)int.Parse(reader["parent_id"].ToString()),
  281. };
  282. }
  283. protected override List<DbFieldInfo> ConvertFields(cms_category model)
  284. {
  285. return new List<DbFieldInfo>
  286. {
  287. new DbFieldInfo { Name = "id", Value = model.id , IsIdentity =true },
  288. new DbFieldInfo { Name = "name", Value = model.name },
  289. new DbFieldInfo { Name = "parent_id", Value = model.parent_id },
  290. };
  291. }
  292. }
  293.  
  294. public class cms_category_extend : cms_category
  295. {
  296. public cms_category mytest1 { get; set; }
  297. public cms_category_extend mytest2 { get; set; }
  298. public string myname { get; set; }
  299. }
  300. public class ucl_grade
  301. {
  302. public int id { get; set; }
  303. public int grade { get; set; }
  304. public string grade_name { get; set; }
  305. }
  306.  
  307. public class UclGradeDataAccess : BaseMapper<ucl_grade>
  308. {
  309. public UclGradeDataAccess(ucl_grade model = null)
  310. {
  311. ContextEntity = model;
  312. }
  313. public override string TableName
  314. {
  315. get { return "ucl_grade"; }
  316. }
  317. protected override ucl_grade ConvertEntity(IDataReader reader)
  318. {
  319. return new ucl_grade
  320. {
  321. id = int.Parse(reader["id"].ToString()),
  322. grade = int.Parse(reader["grade"].ToString()),
  323. grade_name = reader["grade_name"].ToString(),
  324. };
  325. }
  326. protected override List<DbFieldInfo> ConvertFields(ucl_grade model)
  327. {
  328. return new List<DbFieldInfo>
  329. {
  330. new DbFieldInfo { Name = "id", Value = model.id , IsPrimaryKey =true , IsIdentity =true },
  331. new DbFieldInfo { Name = "grade", Value = model.grade },
  332. new DbFieldInfo { Name = "grade_name", Value = model.grade_name },
  333. };
  334. }
  335. }
  336. public enum Status
  337. {
  338. Success
  339. }
  340.  
  341. #endregion
  342.  
  343. }
  344. }

部分测试截图:


Orm成品开源项目地址
https://github.com/PlugNT/util6

一个类搞定SQL条件映射解析,实现轻量简单实用ORM功能的更多相关文章

  1. 一个类搞定UIScrollView那些事

    前言 UIScrollView可以说是我们在日常编程中使用频率最多.扩展性最好的一个类,根据不同的需求和设计,我们都能玩出花来,当然有一些需求是大部分应用通用的,今天就聊一下以下需求,在一个categ ...

  2. 一个类搞定UIScrollView那些事儿

    前言 UIScrollView可以说是我们在日常编程中使用频率最多.扩展性最好的一个类,根据不同的需求和设计,我们都能玩出花来,当然有一些需求是大部分应用通用的,今天就聊一下以下需求,在一个categ ...

  3. Spring Boot 一个依赖搞定 session 共享,没有比这更简单的方案了!

    有的人可能会觉得题目有点夸张,其实不夸张,题目没有使用任何修辞手法!认真读完本文,你就知道松哥说的是对的了! 在传统的单服务架构中,一般来说,只有一个服务器,那么不存在 Session 共享问题,但是 ...

  4. 将你的前端应用打包成docker镜像并部署到服务器?仅需一个脚本搞定

    1.前言 前段时间,自己搞了个阿里云的服务器.想自己在上面折腾,但是不想因为自己瞎折腾而污染了现有的环境.毕竟,现在的阿里云已经没有免费的快照服务了.要想还原的话,最简单的办法就是重新装系统.而一旦重 ...

  5. Jquery一个slideToggle搞定div的隐藏与显示

    Jquery一个slideToggle搞定div的隐藏与显示 <!DOCTYPE html> <html> <head> <script src=" ...

  6. 一个命令搞定 Web 国际化

    背景 随着出海的业务越来越多,web 应用面临越来越多的国际化的工作.如何高效,高质量的完成 Web 前端国际化工作,已经是摆在 web 前端同学的急需解决的问题. i18n-helper-cli 是 ...

  7. 一个注解搞定SpringBoot接口定制属性加解密

    前言 上个月公司另一个团队做的新项目上线后大体上运行稳定,但包括研发负责人在内的两个人在项目上线后立马就跳槽了,然后又交接给了我这个「垃圾回收人员」. 本周甲方另一个厂家的监控平台扫描到我们这个项目某 ...

  8. 如何让两个div在同一行显示?一个float搞定

    最近在学习div和css,遇到了一些问题也解决了很多以前以为很难搞定的问题.比如:如何让两个div显示在同一行呢?(不是用table表格,table对SE不太友好)其实,<div> 是一个 ...

  9. iOS之下拉放大,上推缩小,一个方法搞定

    先来看看效果吧. 讲讲大概的实现思路:1、创建头部的视图和tableview,需要注意的是tableview要设置contentInset,contentInsent 的顶部要和头部视图的背景图的高度 ...

随机推荐

  1. sparkSQL中的example学习(1)

    SparkSQLDemo.scala import org.apache.spark.sql.{Row, SparkSession} import org.apache.spark.sql.types ...

  2. SQL 触发器 新建时删除相同数据

    --create alter trigger [dbo].[trigger_sqsj] on [dbo].[lctnrcrd] after INSERT as BEGIN ) id ),dlr,) d ...

  3. 3-3 groupby操作

    Pandas章节应用的数据可以在以下链接下载:  https://files.cnblogs.com/files/AI-robort/Titanic_Data-master.zip .caret, . ...

  4. 其他综合-Kickstart无人值守安装系统CentOS 7

    Kickstart无人值守安装系统CentOS 7 1.概述 1.1 关于PXE Preboot Execution Environment 翻译过来就是预启动执行环境:简称 PXE :传统安装操作系 ...

  5. day39_8_23mysql的其他内容(视图等)

    一.视图 MySQL中有一种比较方便的表,就是视图(view). 什么是视图? 视图就是通过查询获得一张虚拟表,然后将其保存,下次可以直接使用这个视图. 使用视图就可以不需要重复查询/连接表,在代码层 ...

  6. 生产者和消费者模型producer and consumer(单线程下实现高并发)

    #1.生产者和消费者模型producer and consumer modelimport timedef producer(): ret = [] for i in range(2): time.s ...

  7. LG2598/BZOJ1412 「ZJOI2009」狼和羊的故事 最小割

    问题描述 LG2598 BZOJ1412 题解 看到要把狼和羊两个物种分开 自然想到最小割. 发现\((x,y)\)可以向上下左右走以获得贡献,所以建边:\((x,y),(x-1,y)\),\((x, ...

  8. web框架--tornado自定义分页

    1.tornado_main.py #!/usr/bin/env python # -*- coding: utf-8 -*- import tornado.web import tornado.io ...

  9. ABP 下载源码报错

    ASP.NET Boilerplate 下载地址应该是这个:https://github.com/aspnetboilerplate/aspnetboilerplate/tree/v1.5.2 下载的 ...

  10. 解决Windows更新错误0x80240034

    Windows update错误0x80240034 笔者平台:WIn10预览版 微软官方文档: https://support.microsoft.com/en-us/help/929833/use ...