/src/Framework/CoolCode.Data.Xml/Repository.cs
C# | 337 lines | 215 code | 52 blank | 70 comment | 11 complexity | fbe6a3668ed0b4c6db201461355a77ec MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Data.Linq;
- using System.Xml.Linq;
- using System.Reflection;
- using System.Linq.Expressions;
- using CoolCode.Reflection;
- using CoolCode.Caching;
- using CoolCode.Linq;
-
- namespace CoolCode.Data.Xml
- {
- public class Repository<T> : IRepository<T>, IXmlTable, IQueryable<T>, IEnumerable<T>, IDisposable where T : class
- {
- private static readonly string entityName = typeof(T).Name;
- private static ICacheStrategy typeCache;
- private static Func<XElement, T, bool> _condition;
- private static Func<T, XElement> _entityToXElement;
- private static bool _initial = false;
- private IDataContext context;
- private XmlQueryable<T> table;
-
- public XElement Root { get; set; }
- public bool IsChanged { get; set; }
- public string ClassName { get; set; }
-
- internal Repository(IDataContext context)
- {
- this.context = context;
- this.table = new XmlQueryable<T>((IQueryExecutor)context);
- Initialize();
- }
-
- private void Initialize()
- {
- if (!_initial)
- {
- typeCache = new HashCacheStrategy();
- ExpressionBuilder exprBuilder = new ExpressionBuilder();
- _condition = exprBuilder.PrimaryKey<T>().Compile();
- _entityToXElement = exprBuilder.ToXElementExpression<T>().Compile();
- _initial = true;
- }
- }
-
- //private XmlQueryable<T> _table = null;
-
- //private XmlQueryable<T> table
- //{
- // get
- // {
- // if (_table == null)
- // _table = new XmlQueryable<T>((IQueryExecutor)context);
- // return _table;
- // }
- //}
-
- #region IRepository<T> Members
-
- public virtual void Insert(T entity)
- {
- var xe = _entityToXElement(entity); //XmlConvert.Entity2Xml<T>(entity);
- Root.Add(xe);
- IsChanged = true;
- }
-
- public virtual void Insert(IEnumerable<T> list)
- {
- foreach (T entity in list)
- {
- var xe = XmlConvert.Entity2Xml<T>(entity);
- Root.Add(xe);
- }
- IsChanged = true;
- }
-
- public virtual void Update(T entity)
- {
- Delete(entity);
- Insert(entity);
- //SaveByPrimaryKeys(entity);
- IsChanged = true;
- }
-
- //public virtual void Update(T entity, T original)
- //{
- // db.Attach(entity, original);
- //}
-
- public virtual void Update(IEnumerable<T> list)
- {
- foreach (T entity in list)
- {
- var xe = XmlConvert.Entity2Xml<T>(entity);
- Root.Add(xe);
- }
- IsChanged = true;
- }
-
- public virtual void Delete(T entity)
- {
- DeleteByPrimaryKeys(entity);
- IsChanged = true;
- }
-
- public virtual void Delete(IQueryable<T> query)
- {
- Delete(query.ToList());
- }
-
- public virtual void Delete(IEnumerable<T> list)
- {
- //Get PrimaryKeys
- string[] primaryKeys = typeCache.GetItem<T>("ColumnAttribute") as string[];
- if (primaryKeys == null)
- {
- primaryKeys = BLReflection.GetPropFrom<System.Data.Linq.Mapping.ColumnAttribute, T>(c => c.IsPrimaryKey);
- typeCache.AddItem<T>(primaryKeys, "ColumnAttribute");
- }
- int len = primaryKeys.Length;
- string[] pkValue = new string[len];
-
- //Initial Expression
- // instance
- ParameterExpression s = Expression.Parameter(typeof(XElement), "s");
- // method
- var m = typeof(XElement).GetMethod("Element", new Type[] { typeof(XName) });
- Expression cond = Expression.Constant(false);
- // Expression condTrue = Expression.Constant(true );
- MemberExpression[] props = new MemberExpression[len];
-
- for (int i = 0; i < len; i++)
- {
- var mcall = Expression.Call(s, m,
- new Expression[] { Expression.Constant((XName)primaryKeys[i], typeof(XName)) } // arguments
- );
- props[i] = Expression.Property(mcall, "Value");
- }
-
- //Join Expression
- foreach (var entity in list)
- {
- Expression subcond = null;
- for (int i = 0; i < len; i++)
- {
- //Method 1: Get Property and cache it for reuse
- var p = typeCache.GetItem<T>("Property" + primaryKeys[i]) as PropertyInfo;
- if (p == null)
- {
- Type t = typeof(T);
- p = t.GetProperty(primaryKeys[i]);
- typeCache.AddItem<T>(p, "Property" + primaryKeys[i]);
- }
- pkValue[i] = XmlConvert.SerializeObject(p.GetValue(entity, null));
-
- //Method 2: Get Property directly every time
- // pkValue[i] = XmlConvert.SerializeObject(BLReflection.GetPropValue(TEntity, primaryKeys[i]));
-
- //Join Condition
- var value = Expression.Constant(pkValue[i], typeof(string));
- if (i == 0)
- subcond = BinaryExpression.Equal(props[i], value);
- else
- subcond = BinaryExpression.AndAlso(subcond, BinaryExpression.Equal(props[i], value));
- }
- cond = BinaryExpression.OrElse(cond, subcond);
- }
-
- // lambda
- var lambda = Expression.Lambda<Func<XElement, bool>>(cond, new ParameterExpression[] { s });
-
- var xe = Root.Descendants(ClassName).Where(lambda.Compile());
- xe.Remove();
-
- IsChanged = true;
- }
-
- public virtual void Delete(Expression<Func<T, bool>> predicate)
- {
- var query = XmlContext.Query<T>(predicate, this.context);
- query.Remove();
- IsChanged = true;
- }
-
- public virtual IQueryable<T> In<P>(Expression<Func<T, P>> property, params P[] values)
- {
- throw new NotImplementedException();
- }
-
- public virtual IQueryable<T> Query()
- {
- //return table;
- throw new NotImplementedException();
- }
-
- public virtual IQueryable<T> Query(Expression<Func<T, bool>> predicate)
- {
- //return table.Where(predicate);
- throw new NotImplementedException();
- }
-
- //IQueryable<T> IRepository<T>.Where(Expression<Func<T, bool>> predicate)
- //{
- // //return table.Where(predicate);
- // throw new NotImplementedException();
- //}
-
- public virtual T Get(Expression<Func<T, bool>> predicate)
- {
- //return table.FirstOrDefault(predicate);
- throw new NotImplementedException();
- }
-
-
- #endregion
-
- #region IEnumerable<T> Members
-
- public IEnumerator<T> GetEnumerator()
- {
- return ((IEnumerable<T>)table).GetEnumerator();
- }
-
- #endregion
-
- #region IEnumerable Members
-
- System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
- {
- return this.GetEnumerator();
- }
-
- #endregion
-
- #region IQueryable Members
-
- Type IQueryable.ElementType
- {
- get
- {
- return typeof(T);
- }
- }
-
- Expression IQueryable.Expression
- {
- get
- {
- return ((IQueryable)table).Expression; // return Expression.Constant(table);
- }
- }
-
- IQueryProvider IQueryable.Provider
- {
- get { return ((IQueryable)table).Provider; }
- }
-
- #endregion
-
- #region IDisposable Members
-
- public virtual void Dispose()
- {
- if (context != null)
- {
- context.Dispose();
- }
- }
-
- #endregion
-
- #region private methods
-
- private void DeleteByPrimaryKeys(T entity)
- {
- var cond = getConditionDelegate(entity);
- var xe = Root.Descendants(ClassName).Where(cond);
- xe.Remove();
- }
-
- private void SaveByPrimaryKeys(T entity)
- {
- DeleteByPrimaryKeys(entity);
- var xe = _entityToXElement(entity); //XmlConvert.Entity2Xml<T>(TEntity);
- Root.Add(xe);
- }
-
- private Func<XElement, bool> getConditionDelegate(T entity)
- {
- return (XElement x) => _condition(x, entity);
- }
-
- #region Old Methods
- /*
- private Func<XElement, bool> PrimaryKeyExpression(T TEntity)
- {
- string[] primaryKeys = typeCache.GetItem<T>("ColumnAttribute") as string[];
- if (primaryKeys == null)
- {
- primaryKeys = BLReflection.GetPropFrom<System.Data.Linq.Mapping.ColumnAttribute, T>(c => c.IsPrimaryKey);
- typeCache.AddItem<T>(primaryKeys, "ColumnAttribute");
- }
- return PrimaryKeyExpression(TEntity, primaryKeys);
- }
-
- private Func<XElement, bool> PrimaryKeyExpression(T TEntity, string[] primaryKeys)
- {
- string[] pkValue = new string[primaryKeys.Length];
-
- for (int i = 0; i < primaryKeys.Length; i++)
- {
- //Method 1: Get Property and cache it for reuse
- var p = typeCache.GetItem<T>("Property" + primaryKeys[i]) as PropertyInfo;
- if (p == null)
- {
- Type t = typeof(T);
- p = t.GetProperty(primaryKeys[i]);
- typeCache.AddItem<T>(p, "Property" + primaryKeys[i]);
- }
- pkValue[i] = XmlConvert.SerializeObject(p.GetValue(TEntity, null));
- }
-
- ExpressionBuilder builder = new ExpressionBuilder();
- var condExpr = builder.Where(primaryKeys, pkValue);
- var cond = condExpr.Compile();
-
- return cond;
- }
- */
- #endregion
-
- #endregion
-
- }
- }