EFModelExt.cs 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Data.Common;
  6. using System.Data.Entity;
  7. using System.Data.Entity.Infrastructure;
  8. using System.Transactions;
  9. using System.Data.SqlClient;
  10. using System.Linq.Expressions;
  11. using System.Data;
  12. using Bowin.Common.Linq.DB;
  13. using System.Configuration;
  14. using System.Reflection;
  15. using System.Data.Entity.Core.Objects;
  16. using System.Data.Entity.Core.Objects.DataClasses;
  17. using System.Data.Linq.Mapping;
  18. using System.Data.Entity.Core;
  19. using EntityFramework.Extensions;
  20. using AutoMapper;
  21. using System.Dynamic;
  22. namespace Bowin.Common.Linq.Entity
  23. {
  24. public static class EFModelExt
  25. {
  26. // public static void Delete<TEntity, TKeys>(this DbSet<TEntity> dbSet, IEnumerable<TKeys> keyList) where TEntity : class
  27. // {
  28. // var keyType = typeof(TKeys);
  29. // string tableName = typeof(TEntity).Name;
  30. // IList<TEntity> result = new List<TEntity>();
  31. // if (keyType.IsValueType || keyType.Name.StartsWith("String"))
  32. // {
  33. // throw (new EntityException("keyList参数必须是复杂类型的列表。"));
  34. // }
  35. // string tmpTableName = "##DeleteTemp" + Guid.NewGuid().ToString().Replace("-", "");
  36. // SqlConnection conn;
  37. // if (SqlConnectionManager.IsGlobalConnectionStarted)
  38. // {
  39. // conn = SqlConnectionManager.GetConnection(dbSet.AsQueryable().GetConnectionKey());
  40. // }
  41. // else
  42. // {
  43. // //conn = new SqlConnection(dbSet.AsQueryable().GetConnection().ConnectionString);
  44. // conn = (SqlConnection)dbSet.AsQueryable().GetConnection();
  45. // }
  46. // conn.BulkCopyToTempTable(tmpTableName, keyList);
  47. // string sql = @"
  48. //delete t
  49. //from " + tableName + @" t
  50. //inner join " + tmpTableName + @" tmp on ";
  51. // var keyExpression = "";
  52. // foreach (var property in keyType.GetProperties())
  53. // {
  54. // if (property.PropertyType.IsValueType || property.PropertyType.Name.StartsWith("String"))
  55. // {
  56. // var field = property.Name;
  57. // if (keyExpression != "")
  58. // {
  59. // keyExpression += " and ";
  60. // }
  61. // keyExpression += "t.[" + field + "]" + "=tmp.[" + field + "]";
  62. // }
  63. // }
  64. // sql += keyExpression;
  65. // var command = new SqlCommand(sql, conn);
  66. // command.CommandTimeout = 12000;
  67. // command.CommandType = CommandType.Text;
  68. // command.ExecuteNonQuery();
  69. // command.CommandText = "drop table " + tmpTableName;
  70. // command.CommandType = System.Data.CommandType.Text;
  71. // command.ExecuteNonQuery();
  72. // if (!SqlConnectionManager.IsGlobalConnectionStarted)
  73. // {
  74. // conn.Close();
  75. // }
  76. // }
  77. // public static void Delete<TEntity, TKeys, TMatchKey>(this DbSet<TEntity> dbSet, IEnumerable<TKeys> keyList, Expression<Func<TEntity, TMatchKey>> singleKey) where TEntity : class
  78. // {
  79. // var keyType = typeof(TKeys);
  80. // string tableName = typeof(TEntity).Name;
  81. // var singleColumnName = "";
  82. // IList<TEntity> result = new List<TEntity>();
  83. // #region 检查参数输入
  84. // if (keyType.IsValueType || keyType.Name.StartsWith("String"))
  85. // {
  86. // singleColumnName = "TmpColumn";
  87. // }
  88. // else
  89. // {
  90. // throw (new EntityException("keyList参数必须是基础类型的列表。"));
  91. // }
  92. // if (singleKey.Body.NodeType != ExpressionType.MemberAccess)
  93. // {
  94. // throw (new EntityException("singleKey参数必须是MemberAccess类型的Expression"));
  95. // }
  96. // #endregion
  97. // string tmpTableName = "##DeleteTemp" + Guid.NewGuid().ToString().Replace("-", "");
  98. // SqlConnection conn;
  99. // if (SqlConnectionManager.IsGlobalConnectionStarted)
  100. // {
  101. // conn = SqlConnectionManager.GetConnection(dbSet.AsQueryable().GetConnectionKey());
  102. // }
  103. // else
  104. // {
  105. // //conn = new SqlConnection(dbSet.AsQueryable().GetConnection().ConnectionString);
  106. // conn = (SqlConnection)dbSet.AsQueryable().GetConnection();
  107. // }
  108. // conn.BulkCopyToTempTable(tmpTableName, keyList, singleColumnName);
  109. // string sql = @"
  110. //delete t
  111. //from " + tableName + @" t
  112. //inner join " + tmpTableName + @" tmp on ";
  113. // if (singleColumnName != "")
  114. // {
  115. // sql += "t.[" + ((MemberExpression)singleKey.Body).Member.Name + "]=tmp.TmpColumn";
  116. // }
  117. // var command = new SqlCommand(sql, conn);
  118. // command.CommandTimeout = 12000;
  119. // command.CommandType = CommandType.Text;
  120. // command.ExecuteNonQuery();
  121. // command.CommandText = "drop table " + tmpTableName;
  122. // command.CommandType = System.Data.CommandType.Text;
  123. // command.ExecuteNonQuery();
  124. // if (!SqlConnectionManager.IsGlobalConnectionStarted)
  125. // {
  126. // conn.Close();
  127. // }
  128. // }
  129. // public static void Delete<TEntity, TKeys, TMatchKey>(this DbSet<TEntity> dbSet, SqlConnection db, IEnumerable<TKeys> keyList, Expression<Func<TEntity, TMatchKey>> singleKey) where TEntity : class
  130. // {
  131. // var keyType = typeof(TKeys);
  132. // string tableName = typeof(TEntity).Name;
  133. // var singleColumnName = "";
  134. // IList<TEntity> result = new List<TEntity>();
  135. // #region 检查参数输入
  136. // if (keyType.IsValueType || keyType.Name.StartsWith("String"))
  137. // {
  138. // singleColumnName = "TmpColumn";
  139. // }
  140. // else
  141. // {
  142. // throw (new EntityException("keyList参数必须是基础类型的列表。"));
  143. // }
  144. // if (singleKey.Body.NodeType != ExpressionType.MemberAccess)
  145. // {
  146. // throw (new EntityException("singleKey参数必须是MemberAccess类型的Expression"));
  147. // }
  148. // #endregion
  149. // string tmpTableName = "##DeleteTemp" + Guid.NewGuid().ToString().Replace("-", "");
  150. // db.BulkCopyToTempTable(tmpTableName, keyList, singleColumnName);
  151. // string sql = @"
  152. //delete t
  153. //from " + tableName + @" t
  154. //inner join " + tmpTableName + @" tmp on ";
  155. // if (singleColumnName != "")
  156. // {
  157. // sql += "t.[" + ((MemberExpression)singleKey.Body).Member.Name + "]=tmp.TmpColumn";
  158. // }
  159. // var command = new SqlCommand(sql, db);
  160. // command.CommandTimeout = 12000;
  161. // command.CommandType = CommandType.Text;
  162. // command.ExecuteNonQuery();
  163. // command.CommandText = "drop table " + tmpTableName;
  164. // command.CommandType = System.Data.CommandType.Text;
  165. // command.ExecuteNonQuery();
  166. // }
  167. /// <summary>
  168. /// 只有预计关键字数量比较多的时候才使用
  169. /// </summary>
  170. /// <typeparam name="TEntity"></typeparam>
  171. /// <typeparam name="TKeys"></typeparam>
  172. /// <param name="queryable"></param>
  173. /// <param name="keyList"></param>
  174. /// <returns></returns>
  175. public static IList<TEntity> SelectByKeys<TEntity, TKeys>(this IQueryable<TEntity> queryable, IEnumerable<TKeys> keyList) where TEntity : class
  176. {
  177. var keyType = typeof(TKeys);
  178. IList<TEntity> result = new List<TEntity>();
  179. var resultProperties = typeof(TEntity).GetProperties();
  180. if (keyType.IsValueType || keyType.Name.StartsWith("String"))
  181. {
  182. throw (new EntityException("keyList参数必须是复杂类型的列表。"));
  183. }
  184. var tableGuid = Guid.NewGuid().ToString().Replace("-", "");
  185. var columnString = tableGuid.Substring(10, 4);
  186. string tmpTableName = "##SelectTemp" + tableGuid;
  187. SqlConnection conn;
  188. if (SqlConnectionManager.IsGlobalConnectionStarted)
  189. {
  190. conn = SqlConnectionManager.GetConnection(queryable.GetConnectionKey());
  191. }
  192. else
  193. {
  194. //conn = new SqlConnection(queryable.GetConnection().ConnectionString);
  195. conn = (SqlConnection)queryable.GetConnection();
  196. }
  197. var parameters = queryable.GetParamters();
  198. conn.BulkCopyToTempTable(tmpTableName, keyList);
  199. string sql = @"
  200. select t.*
  201. from (
  202. " + queryable.ToString() + @"
  203. ) t
  204. inner join " + tmpTableName + @" tmp on ";
  205. var keyExpression = "";
  206. foreach (var property in keyType.GetProperties())
  207. {
  208. if (property.PropertyType.IsValueType || property.PropertyType.Name.StartsWith("String"))
  209. {
  210. var field = property.Name;
  211. if (keyExpression != "")
  212. {
  213. keyExpression += " and ";
  214. }
  215. keyExpression += "t.[" + field + "]" + "=tmp.[" + field + "]";
  216. }
  217. }
  218. sql += keyExpression;
  219. var command = new SqlCommand(sql, conn);
  220. command.CommandTimeout = 12000;
  221. command.CommandType = CommandType.Text;
  222. foreach (var parameter in parameters)
  223. {
  224. SqlParameter sqlParameter = new SqlParameter();
  225. sqlParameter.ParameterName = parameter.Name;
  226. sqlParameter.Value = parameter.Value;
  227. command.Parameters.Add(sqlParameter);
  228. }
  229. var reader = command.ExecuteReader();
  230. result = ParseDataReaderToEntity<TEntity>(queryable.Expression, reader);
  231. command.CommandText = "drop table " + tmpTableName;
  232. command.CommandType = System.Data.CommandType.Text;
  233. command.ExecuteNonQuery();
  234. if (!SqlConnectionManager.IsGlobalConnectionStarted)
  235. {
  236. conn.Close();
  237. }
  238. return result;
  239. }
  240. private static List<TEntity> ParseDataReaderToEntity<TEntity>(SqlDataReader reader)
  241. {
  242. var result = new List<TEntity>();
  243. var entityType = typeof(TEntity);
  244. try
  245. {
  246. var resultProperties = entityType.GetProperties();
  247. while (reader.Read())
  248. {
  249. TEntity entity;
  250. if (!entityType.Name.Contains("<>f__AnonymousType"))
  251. {
  252. entity = (TEntity)entityType.Assembly.CreateInstance(entityType.FullName);
  253. for (var i = 0; i < resultProperties.Length; i++)
  254. {
  255. try
  256. {
  257. resultProperties[i].SetValue(entity, reader[resultProperties[i].Name], null);
  258. }
  259. catch
  260. {
  261. }
  262. }
  263. }
  264. else
  265. {
  266. var objAttrs = new object[resultProperties.Length];
  267. for (var i = 0; i < resultProperties.Length; i++)
  268. {
  269. objAttrs[i] = reader[resultProperties[i].Name];
  270. }
  271. entity = (TEntity)Activator.CreateInstance(entityType, objAttrs);
  272. }
  273. result.Add(entity);
  274. }
  275. }
  276. catch
  277. { }
  278. finally
  279. {
  280. reader.Close();
  281. }
  282. return result;
  283. }
  284. private static List<TEntity> ParseDataReaderToEntity<TEntity>(Expression queryExpression, SqlDataReader reader)
  285. {
  286. if (queryExpression.NodeType != ExpressionType.Call)
  287. {
  288. return ParseDataReaderToEntity<TEntity>(reader);
  289. }
  290. if (!(((MethodCallExpression)queryExpression).Method.Name == "Select" && ((MethodCallExpression)queryExpression).Arguments.Count == 2))
  291. {
  292. return ParseDataReaderToEntity<TEntity>(reader);
  293. }
  294. if (((MethodCallExpression)queryExpression).Arguments[1].NodeType != ExpressionType.Quote)
  295. {
  296. return ParseDataReaderToEntity<TEntity>(reader);
  297. }
  298. var initialExpression = ((UnaryExpression)((MethodCallExpression)queryExpression).Arguments[1]).Operand;
  299. if (initialExpression.NodeType == ExpressionType.Lambda)
  300. {
  301. var bodyExpression = ((LambdaExpression)initialExpression).Body;
  302. if (bodyExpression.NodeType == ExpressionType.MemberInit)
  303. {
  304. var bindList = ((MemberInitExpression)bodyExpression).Bindings;
  305. var result = new List<TEntity>();
  306. var entityType = typeof(TEntity);
  307. try
  308. {
  309. while (reader.Read())
  310. {
  311. TEntity entity;
  312. var offset = reader.FieldCount - bindList.Count;
  313. if (!entityType.Name.Contains("<>f__AnonymousType"))
  314. {
  315. entity = (TEntity)entityType.Assembly.CreateInstance(entityType.FullName);
  316. for (var i = 0; i < bindList.Count; i++)
  317. {
  318. try
  319. {
  320. ((PropertyInfo)bindList[i].Member).SetValue(entity, reader[i + offset], null);
  321. }
  322. catch
  323. {
  324. }
  325. }
  326. }
  327. else
  328. {
  329. var objAttrs = new object[bindList.Count];
  330. for (var i = 0; i < bindList.Count; i++)
  331. {
  332. objAttrs[i] = reader[i];
  333. }
  334. entity = (TEntity)Activator.CreateInstance(entityType, objAttrs);
  335. }
  336. result.Add(entity);
  337. }
  338. }
  339. catch
  340. { }
  341. finally
  342. {
  343. reader.Close();
  344. }
  345. return result;
  346. }
  347. else
  348. {
  349. return ParseDataReaderToEntity<TEntity>(reader);
  350. }
  351. }
  352. else
  353. {
  354. return ParseDataReaderToEntity<TEntity>(reader);
  355. }
  356. }
  357. /// <summary>
  358. /// 只有预计关键字数量比较多的时候才使用
  359. /// </summary>
  360. /// <typeparam name="TEntity"></typeparam>
  361. /// <typeparam name="TKeys"></typeparam>
  362. /// <param name="repository"></param>
  363. /// <param name="keyList"></param>
  364. /// <returns></returns>
  365. public static IList<TEntity> SelectByKeys<TEntity, TKeys>(this DbSet<TEntity> dbSet, IEnumerable<TKeys> keyList) where TEntity : class
  366. {
  367. var keyType = typeof(TKeys);
  368. string tableName = typeof(TEntity).Name;
  369. IList<TEntity> result = new List<TEntity>();
  370. var resultProperties = typeof(TEntity).GetProperties();
  371. if (keyType.IsValueType || keyType.Name.StartsWith("String"))
  372. {
  373. throw (new EntityException("keyList参数必须是复杂类型的列表。"));
  374. }
  375. string tmpTableName = "##SelectTemp" + Guid.NewGuid().ToString().Replace("-", "");
  376. SqlConnection conn;
  377. if (SqlConnectionManager.IsGlobalConnectionStarted)
  378. {
  379. conn = SqlConnectionManager.GetConnection(dbSet.AsQueryable().GetConnectionKey());
  380. }
  381. else
  382. {
  383. //conn = new SqlConnection(dbSet.AsQueryable().GetConnection().ConnectionString);
  384. conn = (SqlConnection)dbSet.AsQueryable().GetConnection();
  385. }
  386. conn.BulkCopyToTempTable(tmpTableName, keyList);
  387. string sql = @"
  388. select t.*
  389. from " + tableName + @" t
  390. inner join " + tmpTableName + @" tmp on ";
  391. var keyExpression = "";
  392. foreach (var property in keyType.GetProperties())
  393. {
  394. if (property.PropertyType.IsValueType || property.PropertyType.Name.StartsWith("String"))
  395. {
  396. var field = property.Name;
  397. if (keyExpression != "")
  398. {
  399. keyExpression += " and ";
  400. }
  401. keyExpression += "t.[" + field + "]" + "=tmp.[" + field + "]";
  402. }
  403. }
  404. sql += keyExpression;
  405. var command = new SqlCommand(sql, conn);
  406. command.CommandTimeout = 12000;
  407. command.CommandType = CommandType.Text;
  408. var reader = command.ExecuteReader();
  409. result = ParseDataReaderToEntity<TEntity>(reader);
  410. command.CommandText = "drop table " + tmpTableName;
  411. command.CommandType = System.Data.CommandType.Text;
  412. command.ExecuteNonQuery();
  413. if (!SqlConnectionManager.IsGlobalConnectionStarted)
  414. {
  415. conn.Close();
  416. }
  417. return result;
  418. }
  419. public static IList<TEntity> SelectByKeys<TEntity, TKeys, TMatchKey>(this DbSet<TEntity> dbSet, IEnumerable<TKeys> keyList, Expression<Func<TEntity, TMatchKey>> singleKey) where TEntity : class
  420. {
  421. var keyType = typeof(TKeys);
  422. string tableName = typeof(TEntity).Name;
  423. var singleColumnName = "";
  424. IList<TEntity> result = new List<TEntity>();
  425. var resultProperties = typeof(TEntity).GetProperties();
  426. #region 检查参数输入
  427. if (keyType.IsValueType || keyType.Name.StartsWith("String"))
  428. {
  429. singleColumnName = "TmpColumn";
  430. }
  431. else
  432. {
  433. throw (new EntityException("keyList参数必须是基础类型的列表。"));
  434. }
  435. if (singleKey.Body.NodeType != ExpressionType.MemberAccess)
  436. {
  437. throw (new EntityException("singleKey参数必须是MemberAccess类型的Expression"));
  438. }
  439. #endregion
  440. string tmpTableName = "##SelectTemp" + Guid.NewGuid().ToString().Replace("-", "");
  441. SqlConnection conn;
  442. if (SqlConnectionManager.IsGlobalConnectionStarted)
  443. {
  444. conn = SqlConnectionManager.GetConnection(dbSet.AsQueryable().GetConnectionKey());
  445. }
  446. else
  447. {
  448. //conn = new SqlConnection(dbSet.AsQueryable().GetConnection().ConnectionString);
  449. conn = (SqlConnection)dbSet.AsQueryable().GetConnection();
  450. }
  451. conn.BulkCopyToTempTable(tmpTableName, keyList, singleColumnName);
  452. string sql = @"
  453. select t.*
  454. from " + tableName + @" t
  455. inner join " + tmpTableName + @" tmp on ";
  456. if (singleColumnName != "")
  457. {
  458. sql += "t.[" + ((MemberExpression)singleKey.Body).Member.Name + "]=tmp.TmpColumn";
  459. }
  460. var command = new SqlCommand(sql, conn);
  461. command.CommandTimeout = 12000;
  462. command.CommandType = CommandType.Text;
  463. var reader = command.ExecuteReader();
  464. result = ParseDataReaderToEntity<TEntity>(reader);
  465. command.CommandText = "drop table " + tmpTableName;
  466. command.CommandType = System.Data.CommandType.Text;
  467. command.ExecuteNonQuery();
  468. if (!SqlConnectionManager.IsGlobalConnectionStarted)
  469. {
  470. conn.Close();
  471. }
  472. return result;
  473. }
  474. public static IList<TEntity> SelectByKeys<TEntity, TKeys, TMatchKey>(this IQueryable<TEntity> queryable, IEnumerable<TKeys> keyList, Expression<Func<TEntity, TMatchKey>> singleKey) where TEntity : class
  475. {
  476. var keyType = typeof(TKeys);
  477. var singleColumnName = "";
  478. IList<TEntity> result = new List<TEntity>();
  479. var resultProperties = typeof(TEntity).GetProperties();
  480. #region 检查参数输入
  481. if (keyType.IsValueType || keyType.Name.StartsWith("String"))
  482. {
  483. singleColumnName = "TmpColumn";
  484. }
  485. else
  486. {
  487. throw (new EntityException("keyList参数必须是基础类型的列表。"));
  488. }
  489. if (singleKey.Body.NodeType != ExpressionType.MemberAccess)
  490. {
  491. throw (new EntityException("singleKey参数必须是MemberAccess类型的Expression"));
  492. }
  493. #endregion
  494. var tableGuid = Guid.NewGuid().ToString().Replace("-", "");
  495. var columnString = tableGuid.Substring(10, 4);
  496. string tmpTableName = "##SelectTemp" + Guid.NewGuid().ToString().Replace("-", "");
  497. SqlConnection conn;
  498. if (SqlConnectionManager.IsGlobalConnectionStarted)
  499. {
  500. conn = SqlConnectionManager.GetConnection(queryable.GetConnectionKey());
  501. }
  502. else
  503. {
  504. //conn = new SqlConnection(queryable.GetConnection().ConnectionString);
  505. conn = (SqlConnection)queryable.GetConnection();
  506. }
  507. var parameters = queryable.GetParamters();
  508. singleColumnName = singleColumnName + columnString;
  509. conn.BulkCopyToTempTable(tmpTableName, keyList, singleColumnName);
  510. string sql = @"
  511. select t.*
  512. from (
  513. " + queryable.ToString() + @"
  514. ) t
  515. inner join " + tmpTableName + @" tmp on ";
  516. if (singleColumnName != "")
  517. {
  518. sql += "t.[" + ((MemberExpression)singleKey.Body).Member.Name + "]=tmp." + singleColumnName;
  519. }
  520. var command = new SqlCommand(sql, conn);
  521. command.CommandTimeout = 12000;
  522. command.CommandType = CommandType.Text;
  523. foreach (var parameter in parameters)
  524. {
  525. SqlParameter sqlParameter = new SqlParameter();
  526. sqlParameter.ParameterName = parameter.Name;
  527. sqlParameter.Value = parameter.Value;
  528. command.Parameters.Add(sqlParameter);
  529. }
  530. var reader = command.ExecuteReader();
  531. result = ParseDataReaderToEntity<TEntity>(queryable.Expression, reader);
  532. command.CommandText = "drop table " + tmpTableName;
  533. command.CommandType = System.Data.CommandType.Text;
  534. command.ExecuteNonQuery();
  535. if (!SqlConnectionManager.IsGlobalConnectionStarted)
  536. {
  537. conn.Close();
  538. }
  539. return result;
  540. }
  541. public static IList<TEntity> SelectByKeys<TEntity, TKeys, TMatchKey>(this DbSet<TEntity> dbSet, SqlConnection db,
  542. IEnumerable<TKeys> keyList, Expression<Func<TEntity, TMatchKey>> singleKey) where TEntity : class
  543. {
  544. var keyType = typeof(TKeys);
  545. string tableName = typeof(TEntity).Name;
  546. var singleColumnName = "";
  547. IList<TEntity> result = new List<TEntity>();
  548. var resultProperties = typeof(TEntity).GetProperties();
  549. #region 检查参数输入
  550. if (keyType.IsValueType || keyType.Name.StartsWith("String"))
  551. {
  552. singleColumnName = "TmpColumn";
  553. }
  554. else
  555. {
  556. throw (new EntityException("keyList参数必须是基础类型的列表。"));
  557. }
  558. if (singleKey.Body.NodeType != ExpressionType.MemberAccess)
  559. {
  560. throw (new EntityException("singleKey参数必须是MemberAccess类型的Expression"));
  561. }
  562. #endregion
  563. string tmpTableName = "##SelectTemp" + Guid.NewGuid().ToString().Replace("-", "");
  564. db.BulkCopyToTempTable(tmpTableName, keyList, singleColumnName);
  565. string sql = @"
  566. select t.*
  567. from " + tableName + @" t
  568. inner join " + tmpTableName + @" tmp on ";
  569. if (singleColumnName != "")
  570. {
  571. sql += "t.[" + ((MemberExpression)singleKey.Body).Member.Name + "]=tmp.TmpColumn";
  572. }
  573. var command = new SqlCommand(sql, db);
  574. command.CommandTimeout = 12000;
  575. command.CommandType = CommandType.Text;
  576. var reader = command.ExecuteReader();
  577. result = ParseDataReaderToEntity<TEntity>(reader);
  578. command.CommandText = "drop table " + tmpTableName;
  579. command.CommandType = System.Data.CommandType.Text;
  580. command.ExecuteNonQuery();
  581. return result;
  582. }
  583. /// <summary>
  584. /// 批次更新
  585. /// </summary>
  586. //public static int Update<TEntity>(this DbContext db, Expression<Func<TEntity, TEntity>> setExpression, Expression<Func<TEntity, bool>> whereExpression) where TEntity : class
  587. //{
  588. // var context = ((IObjectContextAdapter)db).ObjectContext;
  589. // IObjectSet<TEntity> source = context.CreateObjectSet<TEntity>();
  590. // return source.Update(whereExpression, setExpression);
  591. // //return source.Update(setExpression, whereExpression);
  592. //}
  593. //public static void CommitWithoutValidate(this DbContext db)
  594. //{
  595. // db.Configuration.ValidateOnSaveEnabled = false;
  596. // db.SaveChanges();
  597. // db.Configuration.ValidateOnSaveEnabled = true;
  598. //}
  599. ///// <summary>
  600. ///// 批量更新
  601. ///// </summary>
  602. ///// <typeparam name="TEntity"></typeparam>
  603. ///// <typeparam name="TField"></typeparam>
  604. ///// <typeparam name="TKey"></typeparam>
  605. ///// <param name="uow"></param>
  606. ///// <param name="data"></param>
  607. ///// <param name="fields"></param>
  608. ///// <param name="keys"></param>
  609. //public static void Update<TEntity, TField, TKey>(this DbContext db, IList<TEntity> data, Expression<Func<TEntity, TField>> fields,
  610. // Expression<Func<TEntity, TKey>> keys) where TEntity : class
  611. //{
  612. // string setField = "";
  613. // string keyExpression = "";
  614. // string tableName = typeof(TEntity).Name;
  615. // if (fields.Body.NodeType != ExpressionType.MemberAccess && fields.Body.NodeType != ExpressionType.MemberInit && fields.Body.NodeType != ExpressionType.New)
  616. // {
  617. // throw (new EntityException("fields参数必须是MemberAccess、MemberInit或New类型的Expression"));
  618. // }
  619. // if (keys.Body.NodeType != ExpressionType.MemberAccess && keys.Body.NodeType != ExpressionType.MemberInit && keys.Body.NodeType != ExpressionType.New)
  620. // {
  621. // throw (new EntityException("keys参数必须是MemberAccess、MemberInit或New类型的Expression"));
  622. // }
  623. // if (fields.Body.NodeType != ExpressionType.MemberAccess)
  624. // {
  625. // foreach (var bindingMember in ((NewExpression)fields.Body).Members)
  626. // {
  627. // if (bindingMember.MemberType == System.Reflection.MemberTypes.Property)
  628. // {
  629. // if (((System.Reflection.PropertyInfo)(bindingMember)).PropertyType.IsValueType
  630. // || ((System.Reflection.PropertyInfo)(bindingMember)).PropertyType.Name.StartsWith("String"))
  631. // {
  632. // var field = bindingMember.Name;
  633. // if (setField != "")
  634. // {
  635. // setField += ",";
  636. // }
  637. // setField += "[" + field + "]" + "=dest.[" + field + "]";
  638. // }
  639. // }
  640. // }
  641. // }
  642. // else
  643. // {
  644. // if (((MemberExpression)fields.Body).Member.MemberType == System.Reflection.MemberTypes.Property)
  645. // {
  646. // var propertyInfo = ((System.Reflection.PropertyInfo)((MemberExpression)fields.Body).Member);
  647. // if (propertyInfo.PropertyType.IsValueType || propertyInfo.PropertyType.Name.StartsWith("String"))
  648. // {
  649. // setField = "[" + propertyInfo.Name + "]" + "=dest.[" + propertyInfo.Name + "]";
  650. // }
  651. // }
  652. // }
  653. // if (keys.Body.NodeType != ExpressionType.MemberAccess)
  654. // {
  655. // foreach (var bindingMember in ((NewExpression)keys.Body).Members)
  656. // {
  657. // if (bindingMember.MemberType == System.Reflection.MemberTypes.Property)
  658. // {
  659. // if (((System.Reflection.PropertyInfo)(bindingMember)).PropertyType.IsValueType
  660. // || ((System.Reflection.PropertyInfo)(bindingMember)).PropertyType.Name.StartsWith("String"))
  661. // {
  662. // var key = bindingMember.Name;
  663. // if (keyExpression != "")
  664. // {
  665. // keyExpression += " and ";
  666. // }
  667. // keyExpression += "source.[" + key + "]" + "=dest.[" + key + "]";
  668. // }
  669. // }
  670. // }
  671. // }
  672. // else
  673. // {
  674. // if (((MemberExpression)keys.Body).Member.MemberType == System.Reflection.MemberTypes.Property)
  675. // {
  676. // var propertyInfo = ((System.Reflection.PropertyInfo)((MemberExpression)keys.Body).Member);
  677. // if (propertyInfo.PropertyType.IsValueType || propertyInfo.PropertyType.Name.StartsWith("String"))
  678. // {
  679. // keyExpression = "source.[" + propertyInfo.Name + "]" + "=dest.[" + propertyInfo.Name + "]";
  680. // }
  681. // }
  682. // }
  683. // string tmpTableName = "##UpdateTemp" + Guid.NewGuid().ToString().Replace("-", "");
  684. // SqlConnection conn;
  685. // if (SqlConnectionManager.IsGlobalConnectionStarted)
  686. // {
  687. // conn = SqlConnectionManager.GetConnection(db.GetDbConnectionKey());
  688. // }
  689. // else
  690. // {
  691. // conn = new SqlConnection(db.Database.Connection.ConnectionString);
  692. // }
  693. // conn.BulkCopyToTempTable(tmpTableName, data);
  694. // string sql = @"update " + tableName + @" set " + setField + @" from " + tableName + @" source inner join " + tmpTableName + @" dest on " + keyExpression;
  695. // var command = new SqlCommand(sql, conn);
  696. // command.CommandTimeout = 12000;
  697. // command.CommandType = System.Data.CommandType.Text;
  698. // command.ExecuteNonQuery();
  699. // try
  700. // {
  701. // command.CommandText = "drop table " + tmpTableName;
  702. // command.CommandType = System.Data.CommandType.Text;
  703. // command.ExecuteNonQuery();
  704. // }
  705. // catch { }
  706. // if (!SqlConnectionManager.IsGlobalConnectionStarted)
  707. // {
  708. // conn.Close();
  709. // }
  710. //}
  711. ///// <summary>
  712. ///// 批量更新
  713. ///// </summary>
  714. ///// <typeparam name="TEntity"></typeparam>
  715. ///// <typeparam name="TField"></typeparam>
  716. ///// <typeparam name="TKey"></typeparam>
  717. ///// <param name="uow"></param>
  718. ///// <param name="data"></param>
  719. ///// <param name="fields"></param>
  720. ///// <param name="keys"></param>
  721. //public static void Update<TEntity, TField, TKey>(this SqlConnection db, IList<TEntity> data, Expression<Func<TEntity, TField>> fields,
  722. // Expression<Func<TEntity, TKey>> keys) where TEntity : class
  723. //{
  724. // string setField = "";
  725. // string keyExpression = "";
  726. // string tableName = typeof(TEntity).Name;
  727. // if (fields.Body.NodeType != ExpressionType.MemberAccess && fields.Body.NodeType != ExpressionType.MemberInit && fields.Body.NodeType != ExpressionType.New)
  728. // {
  729. // throw (new EntityException("fields参数必须是MemberAccess、MemberInit或New类型的Expression"));
  730. // }
  731. // if (keys.Body.NodeType != ExpressionType.MemberAccess && keys.Body.NodeType != ExpressionType.MemberInit && keys.Body.NodeType != ExpressionType.New)
  732. // {
  733. // throw (new EntityException("keys参数必须是MemberAccess、MemberInit或New类型的Expression"));
  734. // }
  735. // if (fields.Body.NodeType != ExpressionType.MemberAccess)
  736. // {
  737. // foreach (var bindingMember in ((NewExpression)fields.Body).Members)
  738. // {
  739. // if (bindingMember.MemberType == System.Reflection.MemberTypes.Property)
  740. // {
  741. // if (((System.Reflection.PropertyInfo)(bindingMember)).PropertyType.IsValueType
  742. // || ((System.Reflection.PropertyInfo)(bindingMember)).PropertyType.Name.StartsWith("String"))
  743. // {
  744. // var field = bindingMember.Name;
  745. // if (setField != "")
  746. // {
  747. // setField += ",";
  748. // }
  749. // setField += "[" + field + "]" + "=dest.[" + field + "]";
  750. // }
  751. // }
  752. // }
  753. // }
  754. // else
  755. // {
  756. // if (((MemberExpression)fields.Body).Member.MemberType == System.Reflection.MemberTypes.Property)
  757. // {
  758. // var propertyInfo = ((System.Reflection.PropertyInfo)((MemberExpression)fields.Body).Member);
  759. // if (propertyInfo.PropertyType.IsValueType || propertyInfo.PropertyType.Name.StartsWith("String"))
  760. // {
  761. // setField = "[" + propertyInfo.Name + "]" + "=dest.[" + propertyInfo.Name + "]";
  762. // }
  763. // }
  764. // }
  765. // if (keys.Body.NodeType != ExpressionType.MemberAccess)
  766. // {
  767. // foreach (var bindingMember in ((NewExpression)keys.Body).Members)
  768. // {
  769. // if (bindingMember.MemberType == System.Reflection.MemberTypes.Property)
  770. // {
  771. // if (((System.Reflection.PropertyInfo)(bindingMember)).PropertyType.IsValueType
  772. // || ((System.Reflection.PropertyInfo)(bindingMember)).PropertyType.Name.StartsWith("String"))
  773. // {
  774. // var key = bindingMember.Name;
  775. // if (keyExpression != "")
  776. // {
  777. // keyExpression += " and ";
  778. // }
  779. // keyExpression += "source.[" + key + "]" + "=dest.[" + key + "]";
  780. // }
  781. // }
  782. // }
  783. // }
  784. // else
  785. // {
  786. // if (((MemberExpression)keys.Body).Member.MemberType == System.Reflection.MemberTypes.Property)
  787. // {
  788. // var propertyInfo = ((System.Reflection.PropertyInfo)((MemberExpression)keys.Body).Member);
  789. // if (propertyInfo.PropertyType.IsValueType || propertyInfo.PropertyType.Name.StartsWith("String"))
  790. // {
  791. // keyExpression = "source.[" + propertyInfo.Name + "]" + "=dest.[" + propertyInfo.Name + "]";
  792. // }
  793. // }
  794. // }
  795. // string tmpTableName = "##UpdateTemp" + Guid.NewGuid().ToString().Replace("-", "");
  796. // db.BulkCopyToTempTable(tmpTableName, data);
  797. // string sql = @"update " + tableName + @" set " + setField + @" from " + tableName + @" source inner join " + tmpTableName + @" dest on " + keyExpression;
  798. // var command = new SqlCommand(sql, db);
  799. // command.CommandTimeout = 12000;
  800. // command.CommandType = System.Data.CommandType.Text;
  801. // command.ExecuteNonQuery();
  802. // try
  803. // {
  804. // command.CommandText = "drop table " + tmpTableName;
  805. // command.CommandType = System.Data.CommandType.Text;
  806. // command.ExecuteNonQuery();
  807. // }
  808. // catch { }
  809. //}
  810. // /// <summary>
  811. // /// 批量更新
  812. // /// </summary>
  813. // /// <typeparam name="TEntity"></typeparam>
  814. // /// <typeparam name="TUpdateFields"></typeparam>
  815. // /// <param name="db"></param>
  816. // /// <param name="fromCause"></param>
  817. // /// <param name="fields"></param>
  818. // public static void Update<TEntity>(this DbContext db, IQueryable<TEntity> fromCause, Expression<Func<TEntity, TEntity>> fields)
  819. // {
  820. // IList<ObjectParameter> para = new List<ObjectParameter>();
  821. // string sql = fromCause.ToString();
  822. // string setField = "";
  823. // string tableKey = TableKeyDictionary.GetKeyName<TEntity>();
  824. // if (fields.Body.NodeType != ExpressionType.MemberInit)
  825. // {
  826. // throw (new EntityException("fields参数必须是MemberInit类型的Expression"));
  827. // }
  828. // foreach (var bindingExpression in ((MemberInitExpression)fields.Body).Bindings)
  829. // {
  830. // var field = bindingExpression.Member.Name;
  831. // if (setField != "")
  832. // {
  833. // setField += ",";
  834. // }
  835. // if (((System.Linq.Expressions.MemberAssignment)(bindingExpression)).Expression.NodeType == ExpressionType.MemberAccess)
  836. // {
  837. // setField += "[" + field + "]" + "=x.[" + ((MemberExpression)((System.Linq.Expressions.MemberAssignment)(bindingExpression)).Expression).Member.Name + "]";
  838. // }
  839. // else
  840. // {
  841. // var obj = Expression.Lambda(((System.Linq.Expressions.MemberAssignment)(bindingExpression)).Expression).Compile().DynamicInvoke(null);
  842. // setField += "[" + field + "]" + "=@setPara" + field;
  843. // }
  844. // }
  845. // fromCause.GetParamters().ToList().ForEach(x => para.Add(x));
  846. // sql = "update " + typeof(TEntity).Name + " set " + setField + @"
  847. //from " + typeof(TEntity).Name + @" a
  848. //inner join (" + sql + ") x on a.[" + tableKey + "]=x.[" + tableKey + "]";
  849. // db.Database.ExecuteSqlCommand(sql, para.ToArray());
  850. // }
  851. /// <summary>
  852. /// 批次刪除
  853. /// </summary>
  854. public static int Delete<TEntity>(this DbContext db, Expression<Func<TEntity, bool>> whereExpression) where TEntity : class
  855. {
  856. var context = ((IObjectContextAdapter)db).ObjectContext;
  857. IObjectSet<TEntity> source = context.CreateObjectSet<TEntity>();
  858. return source.Delete(whereExpression);
  859. }
  860. public static void Delete(this SqlConnection db, string tableName, string keyName, object keyValue)
  861. {
  862. var initState = db.State;
  863. if (initState == ConnectionState.Closed)
  864. {
  865. db.Open();
  866. }
  867. var sql = @"delete from " + tableName + " where " + keyName + "=@keyValue";
  868. var command = new SqlCommand(sql, db);
  869. command.CommandTimeout = 12000;
  870. command.CommandType = System.Data.CommandType.Text;
  871. command.Parameters.Add("@keyValue", SqlDbType.UniqueIdentifier);
  872. command.Parameters[0].IsNullable = true;
  873. command.Parameters[0].Value = keyValue;
  874. command.ExecuteNonQuery();
  875. if (initState == ConnectionState.Closed)
  876. {
  877. db.Close();
  878. }
  879. }
  880. public static List<string> GetTableColumns(this SqlConnection db, string tableName)
  881. {
  882. var initState = db.State;
  883. if (initState == ConnectionState.Closed)
  884. {
  885. db.Open();
  886. }
  887. var sql = @"
  888. select * from syscolumns c
  889. inner join sysobjects o on c.id=o.id
  890. where o.xtype='U' and o.name='" + tableName + @"'
  891. order by colid";
  892. var da = new SqlDataAdapter(sql, db);
  893. DataTable dt = new DataTable();
  894. da.Fill(dt);
  895. if (initState == ConnectionState.Closed)
  896. {
  897. db.Close();
  898. }
  899. return dt.AsEnumerable().Select(x => x.Field<string>("name")).ToList();
  900. }
  901. //public static void Delete<TEntity>(this DbContext db, TEntity entity) where TEntity : class
  902. //{
  903. // var typeOfEntity = typeof(TEntity);
  904. // var mappingClass = typeOfEntity.Assembly.GetTypes().Where(x => x.Name == typeOfEntity.Name + "_Mapping").FirstOrDefault();
  905. // var tableKeyName = TableKeyDictionary.GetKeyName(entity);
  906. // var keyProperty = typeOfEntity.GetProperty(tableKeyName);
  907. // var tracker = db.ChangeTracker.Entries<TEntity>().Where(x => keyProperty.GetValue(x.Entity, null) == keyProperty.GetValue(entity, null)).FirstOrDefault();
  908. // if (tracker != null)
  909. // {
  910. // db.Set<TEntity>().Remove(tracker.Entity);
  911. // }
  912. // else
  913. // {
  914. // db.Set<TEntity>().Attach(entity);
  915. // db.Set<TEntity>().Remove(entity);
  916. // }
  917. //}
  918. //public static void InsertBatch<TEntity>(this IList<TEntity> data) where TEntity : class
  919. //{
  920. // var db = GetConnections<TEntity>();
  921. // data.ExecuteBulkCopy(db, typeof(TEntity).Name);
  922. //}
  923. public static SqlConnection GetConnections<TEntity>()
  924. {
  925. var blAssembly = Assembly.GetExecutingAssembly();
  926. var entityType = typeof(TEntity);
  927. if (entityType.BaseType != typeof(object))
  928. {
  929. entityType = entityType.BaseType;
  930. }
  931. var myClass = blAssembly.GetTypes()
  932. .Where(x => x.Name.EndsWith("Repository") &&
  933. x.BaseType.GetGenericArguments()[0].FullName == entityType.FullName)
  934. .FirstOrDefault();
  935. string connectionKey = "";
  936. var context = myClass.BaseType.GetGenericArguments()[0].Assembly.GetTypes().Where(x => x.BaseType == typeof(DbContext)).FirstOrDefault();
  937. connectionKey = context.Name;
  938. if (SqlConnectionManager.IsGlobalConnectionStarted)
  939. {
  940. return SqlConnectionManager.GetConnection(connectionKey);
  941. }
  942. else
  943. {
  944. return new SqlConnection(ConfigurationManager.ConnectionStrings[connectionKey].ConnectionString);
  945. }
  946. }
  947. public static PropertyInfo GetPK(this EntityObject value)
  948. {
  949. //var metadata = ((IObjectContextAdapter)this).ObjectContext.MetadataWorkspace;
  950. //var a = metadata.GetItems(DataSpace.OSpace);
  951. return null;
  952. }
  953. }
  954. }