using System.Collections; using System.Linq.Expressions; namespace YLErp.Modules.DataCacheModule { class DataCacheQueryable : IOrderedQueryable { private IQueryable _query; public DataCacheQueryable(IQueryable query) { _query = query ?? throw new ArgumentNullException(nameof(query)); } public Expression Expression => _query.Expression; public Type ElementType => _query.ElementType; public IQueryProvider Provider => new DataCacheQueryProvider(_query.Provider); public IEnumerator GetEnumerator() { var em = Provider.Execute>(Expression); var t = typeof(T); if (t.IsClass && typeof(IClonable).IsAssignableFrom(t)) { em = em.Select(n => ((IClonable)n).Clone()); } return em.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } } class DataCacheQueryProvider : IQueryProvider { readonly IQueryProvider _baseProvider; public DataCacheQueryProvider(IQueryProvider baseProvider) { _baseProvider = baseProvider ?? throw new ArgumentNullException(nameof(baseProvider)); } public IQueryable CreateQuery(Expression expression) { return new DataCacheQueryable(_baseProvider.CreateQuery(expression)); } public IQueryable CreateQuery(Expression expression) { var query = _baseProvider.CreateQuery(expression); var t = typeof(TElement); if (t.IsClass && typeof(IClonable).IsAssignableFrom(t)) { return new DataCacheQueryable(query); } return query; } public object Execute(Expression expression) { return Execute(expression); } public TResult Execute(Expression expression) { return _baseProvider.Execute(expression); } } }