PageRenderTime 65ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Framework/CoolCode.Data.Xml/Repository.cs

https://bitbucket.org/coolcode/ibs
C# | 337 lines | 215 code | 52 blank | 70 comment | 11 complexity | fbe6a3668ed0b4c6db201461355a77ec MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Data.Linq;
  6. using System.Xml.Linq;
  7. using System.Reflection;
  8. using System.Linq.Expressions;
  9. using CoolCode.Reflection;
  10. using CoolCode.Caching;
  11. using CoolCode.Linq;
  12. namespace CoolCode.Data.Xml
  13. {
  14. public class Repository<T> : IRepository<T>, IXmlTable, IQueryable<T>, IEnumerable<T>, IDisposable where T : class
  15. {
  16. private static readonly string entityName = typeof(T).Name;
  17. private static ICacheStrategy typeCache;
  18. private static Func<XElement, T, bool> _condition;
  19. private static Func<T, XElement> _entityToXElement;
  20. private static bool _initial = false;
  21. private IDataContext context;
  22. private XmlQueryable<T> table;
  23. public XElement Root { get; set; }
  24. public bool IsChanged { get; set; }
  25. public string ClassName { get; set; }
  26. internal Repository(IDataContext context)
  27. {
  28. this.context = context;
  29. this.table = new XmlQueryable<T>((IQueryExecutor)context);
  30. Initialize();
  31. }
  32. private void Initialize()
  33. {
  34. if (!_initial)
  35. {
  36. typeCache = new HashCacheStrategy();
  37. ExpressionBuilder exprBuilder = new ExpressionBuilder();
  38. _condition = exprBuilder.PrimaryKey<T>().Compile();
  39. _entityToXElement = exprBuilder.ToXElementExpression<T>().Compile();
  40. _initial = true;
  41. }
  42. }
  43. //private XmlQueryable<T> _table = null;
  44. //private XmlQueryable<T> table
  45. //{
  46. // get
  47. // {
  48. // if (_table == null)
  49. // _table = new XmlQueryable<T>((IQueryExecutor)context);
  50. // return _table;
  51. // }
  52. //}
  53. #region IRepository<T> Members
  54. public virtual void Insert(T entity)
  55. {
  56. var xe = _entityToXElement(entity); //XmlConvert.Entity2Xml<T>(entity);
  57. Root.Add(xe);
  58. IsChanged = true;
  59. }
  60. public virtual void Insert(IEnumerable<T> list)
  61. {
  62. foreach (T entity in list)
  63. {
  64. var xe = XmlConvert.Entity2Xml<T>(entity);
  65. Root.Add(xe);
  66. }
  67. IsChanged = true;
  68. }
  69. public virtual void Update(T entity)
  70. {
  71. Delete(entity);
  72. Insert(entity);
  73. //SaveByPrimaryKeys(entity);
  74. IsChanged = true;
  75. }
  76. //public virtual void Update(T entity, T original)
  77. //{
  78. // db.Attach(entity, original);
  79. //}
  80. public virtual void Update(IEnumerable<T> list)
  81. {
  82. foreach (T entity in list)
  83. {
  84. var xe = XmlConvert.Entity2Xml<T>(entity);
  85. Root.Add(xe);
  86. }
  87. IsChanged = true;
  88. }
  89. public virtual void Delete(T entity)
  90. {
  91. DeleteByPrimaryKeys(entity);
  92. IsChanged = true;
  93. }
  94. public virtual void Delete(IQueryable<T> query)
  95. {
  96. Delete(query.ToList());
  97. }
  98. public virtual void Delete(IEnumerable<T> list)
  99. {
  100. //Get PrimaryKeys
  101. string[] primaryKeys = typeCache.GetItem<T>("ColumnAttribute") as string[];
  102. if (primaryKeys == null)
  103. {
  104. primaryKeys = BLReflection.GetPropFrom<System.Data.Linq.Mapping.ColumnAttribute, T>(c => c.IsPrimaryKey);
  105. typeCache.AddItem<T>(primaryKeys, "ColumnAttribute");
  106. }
  107. int len = primaryKeys.Length;
  108. string[] pkValue = new string[len];
  109. //Initial Expression
  110. // instance
  111. ParameterExpression s = Expression.Parameter(typeof(XElement), "s");
  112. // method
  113. var m = typeof(XElement).GetMethod("Element", new Type[] { typeof(XName) });
  114. Expression cond = Expression.Constant(false);
  115. // Expression condTrue = Expression.Constant(true );
  116. MemberExpression[] props = new MemberExpression[len];
  117. for (int i = 0; i < len; i++)
  118. {
  119. var mcall = Expression.Call(s, m,
  120. new Expression[] { Expression.Constant((XName)primaryKeys[i], typeof(XName)) } // arguments
  121. );
  122. props[i] = Expression.Property(mcall, "Value");
  123. }
  124. //Join Expression
  125. foreach (var entity in list)
  126. {
  127. Expression subcond = null;
  128. for (int i = 0; i < len; i++)
  129. {
  130. //Method 1: Get Property and cache it for reuse
  131. var p = typeCache.GetItem<T>("Property" + primaryKeys[i]) as PropertyInfo;
  132. if (p == null)
  133. {
  134. Type t = typeof(T);
  135. p = t.GetProperty(primaryKeys[i]);
  136. typeCache.AddItem<T>(p, "Property" + primaryKeys[i]);
  137. }
  138. pkValue[i] = XmlConvert.SerializeObject(p.GetValue(entity, null));
  139. //Method 2: Get Property directly every time
  140. // pkValue[i] = XmlConvert.SerializeObject(BLReflection.GetPropValue(TEntity, primaryKeys[i]));
  141. //Join Condition
  142. var value = Expression.Constant(pkValue[i], typeof(string));
  143. if (i == 0)
  144. subcond = BinaryExpression.Equal(props[i], value);
  145. else
  146. subcond = BinaryExpression.AndAlso(subcond, BinaryExpression.Equal(props[i], value));
  147. }
  148. cond = BinaryExpression.OrElse(cond, subcond);
  149. }
  150. // lambda
  151. var lambda = Expression.Lambda<Func<XElement, bool>>(cond, new ParameterExpression[] { s });
  152. var xe = Root.Descendants(ClassName).Where(lambda.Compile());
  153. xe.Remove();
  154. IsChanged = true;
  155. }
  156. public virtual void Delete(Expression<Func<T, bool>> predicate)
  157. {
  158. var query = XmlContext.Query<T>(predicate, this.context);
  159. query.Remove();
  160. IsChanged = true;
  161. }
  162. public virtual IQueryable<T> In<P>(Expression<Func<T, P>> property, params P[] values)
  163. {
  164. throw new NotImplementedException();
  165. }
  166. public virtual IQueryable<T> Query()
  167. {
  168. //return table;
  169. throw new NotImplementedException();
  170. }
  171. public virtual IQueryable<T> Query(Expression<Func<T, bool>> predicate)
  172. {
  173. //return table.Where(predicate);
  174. throw new NotImplementedException();
  175. }
  176. //IQueryable<T> IRepository<T>.Where(Expression<Func<T, bool>> predicate)
  177. //{
  178. // //return table.Where(predicate);
  179. // throw new NotImplementedException();
  180. //}
  181. public virtual T Get(Expression<Func<T, bool>> predicate)
  182. {
  183. //return table.FirstOrDefault(predicate);
  184. throw new NotImplementedException();
  185. }
  186. #endregion
  187. #region IEnumerable<T> Members
  188. public IEnumerator<T> GetEnumerator()
  189. {
  190. return ((IEnumerable<T>)table).GetEnumerator();
  191. }
  192. #endregion
  193. #region IEnumerable Members
  194. System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  195. {
  196. return this.GetEnumerator();
  197. }
  198. #endregion
  199. #region IQueryable Members
  200. Type IQueryable.ElementType
  201. {
  202. get
  203. {
  204. return typeof(T);
  205. }
  206. }
  207. Expression IQueryable.Expression
  208. {
  209. get
  210. {
  211. return ((IQueryable)table).Expression; // return Expression.Constant(table);
  212. }
  213. }
  214. IQueryProvider IQueryable.Provider
  215. {
  216. get { return ((IQueryable)table).Provider; }
  217. }
  218. #endregion
  219. #region IDisposable Members
  220. public virtual void Dispose()
  221. {
  222. if (context != null)
  223. {
  224. context.Dispose();
  225. }
  226. }
  227. #endregion
  228. #region private methods
  229. private void DeleteByPrimaryKeys(T entity)
  230. {
  231. var cond = getConditionDelegate(entity);
  232. var xe = Root.Descendants(ClassName).Where(cond);
  233. xe.Remove();
  234. }
  235. private void SaveByPrimaryKeys(T entity)
  236. {
  237. DeleteByPrimaryKeys(entity);
  238. var xe = _entityToXElement(entity); //XmlConvert.Entity2Xml<T>(TEntity);
  239. Root.Add(xe);
  240. }
  241. private Func<XElement, bool> getConditionDelegate(T entity)
  242. {
  243. return (XElement x) => _condition(x, entity);
  244. }
  245. #region Old Methods
  246. /*
  247. private Func<XElement, bool> PrimaryKeyExpression(T TEntity)
  248. {
  249. string[] primaryKeys = typeCache.GetItem<T>("ColumnAttribute") as string[];
  250. if (primaryKeys == null)
  251. {
  252. primaryKeys = BLReflection.GetPropFrom<System.Data.Linq.Mapping.ColumnAttribute, T>(c => c.IsPrimaryKey);
  253. typeCache.AddItem<T>(primaryKeys, "ColumnAttribute");
  254. }
  255. return PrimaryKeyExpression(TEntity, primaryKeys);
  256. }
  257. private Func<XElement, bool> PrimaryKeyExpression(T TEntity, string[] primaryKeys)
  258. {
  259. string[] pkValue = new string[primaryKeys.Length];
  260. for (int i = 0; i < primaryKeys.Length; i++)
  261. {
  262. //Method 1: Get Property and cache it for reuse
  263. var p = typeCache.GetItem<T>("Property" + primaryKeys[i]) as PropertyInfo;
  264. if (p == null)
  265. {
  266. Type t = typeof(T);
  267. p = t.GetProperty(primaryKeys[i]);
  268. typeCache.AddItem<T>(p, "Property" + primaryKeys[i]);
  269. }
  270. pkValue[i] = XmlConvert.SerializeObject(p.GetValue(TEntity, null));
  271. }
  272. ExpressionBuilder builder = new ExpressionBuilder();
  273. var condExpr = builder.Where(primaryKeys, pkValue);
  274. var cond = condExpr.Compile();
  275. return cond;
  276. }
  277. */
  278. #endregion
  279. #endregion
  280. }
  281. }