123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- using Ant.Common;
- using Ant.Core;
- using Ant.Data;
- using Ant.Descriptors;
- using Ant.Mapper;
- using Ant.ORM;
- using Ant.Query.Mapping;
- using Ant.Utility;
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Data;
- using System.Diagnostics;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Threading;
- namespace Ant.ORM
- {
- class ORMInternalSqlQuery<T> : IEnumerable<T>, IEnumerable
- {
- DataAccess db;
- string _sql;
- DbParam[] _parameters;
- public ORMInternalSqlQuery(DataAccess dbContext, string sql, DbParam[] parameters)
- {
- this.db = dbContext;
- this._sql = sql;
- this._parameters = parameters;
- }
- public IEnumerator<T> GetEnumerator()
- {
- return new QueryEnumerator(this);
- }
- IEnumerator IEnumerable.GetEnumerator()
- {
- return this.GetEnumerator();
- }
- struct QueryEnumerator : IEnumerator<T>
- {
- ORMInternalSqlQuery<T> _internalSqlQuery;
- IDataReader _reader;
- IObjectActivator _objectActivator;
- T _current;
- bool _hasFinished;
- bool _disposed;
- public QueryEnumerator(ORMInternalSqlQuery<T> internalSqlQuery)
- {
- this._internalSqlQuery = internalSqlQuery;
- this._reader = null;
- this._objectActivator = null;
- this._current = default(T);
- this._hasFinished = false;
- this._disposed = false;
- }
- public T Current { get { return this._current; } }
- object IEnumerator.Current { get { return this._current; } }
- public bool MoveNext()
- {
- if (this._hasFinished || this._disposed)
- return false;
- if (this._reader == null)
- {
- this.Prepare();
- }
- if (this._reader.Read())
- {
- this._current = (T)this._objectActivator.CreateInstance(this._reader);
- return true;
- }
- else
- {
- this._reader.Close();
- this._internalSqlQuery.db.Close();
- this._current = default(T);
- this._hasFinished = true;
- return false;
- }
- }
- public void Dispose()
- {
- if (this._disposed)
- return;
- if (this._reader != null)
- {
- if (!this._reader.IsClosed)
- this._reader.Close();
- this._reader.Dispose();
- this._reader = null;
- }
- if (!this._hasFinished)
- {
- this._internalSqlQuery.db.Close();
- this._hasFinished = true;
- }
- this._current = default(T);
- this._disposed = true;
- }
- public void Reset()
- {
- throw new NotSupportedException();
- }
- void Prepare()
- {
- Type type = typeof(T);
- if (AntUtils.IsMapType(type))
- {
- MappingField mf = new MappingField(type, 0);
- this._objectActivator = mf.CreateObjectActivator();
- this._reader = this._internalSqlQuery.db.ExecuteReader(this._internalSqlQuery._sql, this._internalSqlQuery._parameters, CommandBehavior.Default, CommandType.Text);
- return;
- }
- this._reader = this._internalSqlQuery.db.ExecuteReader(this._internalSqlQuery._sql, this._internalSqlQuery._parameters, CommandBehavior.Default, CommandType.Text);
- this._objectActivator = GetObjectActivator(type, this._reader);
- }
- static ObjectActivator GetObjectActivator(Type type, IDataReader reader)
- {
- List<CacheInfo> caches;
- if (!ObjectActivatorCache.TryGetValue(type, out caches))
- {
- if (!Monitor.TryEnter(type))
- {
- return CreateObjectActivator(type, reader);
- }
- try
- {
- caches = ObjectActivatorCache.GetOrAdd(type, new List<CacheInfo>(1));
- }
- finally
- {
- Monitor.Exit(type);
- }
- }
- CacheInfo cache = TryGetCacheInfoFromList(caches, reader);
- if (cache == null)
- {
- lock (caches)
- {
- cache = TryGetCacheInfoFromList(caches, reader);
- if (cache == null)
- {
- ObjectActivator activator = CreateObjectActivator(type, reader);
- cache = new CacheInfo(activator, reader);
- caches.Add(cache);
- }
- }
- }
- return cache.ObjectActivator;
- }
- static ObjectActivator CreateObjectActivator(Type type, IDataReader reader)
- {
- EntityConstructorDescriptor constructorDescriptor = EntityConstructorDescriptor.GetInstance(type.GetConstructor(Type.EmptyTypes));
- EntityMemberMapper mapper = constructorDescriptor.GetEntityMemberMapper();
- Func<IDataReader, ReaderOrdinalEnumerator, ObjectActivatorEnumerator, object> instanceCreator = constructorDescriptor.GetInstanceCreator();
- List<IValueSetter> memberSetters = PrepareValueSetters(type, reader, mapper);
- return new ObjectActivator(instanceCreator, null, null, memberSetters, null);
- }
- static List<IValueSetter> PrepareValueSetters(Type type, IDataReader reader, EntityMemberMapper mapper)
- {
- List<IValueSetter> memberSetters = new List<IValueSetter>(reader.FieldCount);
- MemberInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty);
- MemberInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetField);
- List<MemberInfo> members = new List<MemberInfo>(properties.Length + fields.Length);
- members.AddRange(properties);
- members.AddRange(fields);
- for (int i = 0; i < reader.FieldCount; i++)
- {
- string name = reader.GetName(i);
- var member = members.Where(a => a.Name == name).FirstOrDefault();
- if (member == null)
- {
- member = members.Where(a => string.Equals(a.Name, name, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
- if (member == null)
- continue;
- }
- IMRM mMapper = mapper.GetMemberMapper(member);
- if (mMapper == null)
- continue;
- MappingMemberBinder memberBinder = new MappingMemberBinder(mMapper, i);
- memberSetters.Add(memberBinder);
- }
- return memberSetters;
- }
- static CacheInfo TryGetCacheInfoFromList(List<CacheInfo> caches, IDataReader reader)
- {
- CacheInfo cache = null;
- for (int i = 0; i < caches.Count; i++)
- {
- var item = caches[i];
- if (item.IsTheSameFields(reader))
- {
- cache = item;
- break;
- }
- }
- return cache;
- }
- static readonly System.Collections.Concurrent.ConcurrentDictionary<Type, List<CacheInfo>> ObjectActivatorCache = new System.Collections.Concurrent.ConcurrentDictionary<Type, List<CacheInfo>>();
- }
- public class CacheInfo
- {
- Tuple<string, Type>[] _readerFields;
- ObjectActivator _objectActivator;
- public CacheInfo(ObjectActivator activator, IDataReader reader)
- {
- int fieldCount = reader.FieldCount;
- var readerFields = new Tuple<string, Type>[fieldCount];
- for (int i = 0; i < fieldCount; i++)
- {
- readerFields[i] = new Tuple<string, Type>(reader.GetName(i), reader.GetFieldType(i));
- }
- this._readerFields = readerFields;
- this._objectActivator = activator;
- }
- public ObjectActivator ObjectActivator { get { return this._objectActivator; } }
- public bool IsTheSameFields(IDataReader reader)
- {
- Tuple<string, Type>[] readerFields = this._readerFields;
- int fieldCount = reader.FieldCount;
- if (fieldCount != readerFields.Length)
- return false;
- for (int i = 0; i < fieldCount; i++)
- {
- Tuple<string, Type> tuple = readerFields[i];
- if (reader.GetFieldType(i) != tuple.Item2 || reader.GetName(i) != tuple.Item1)
- {
- return false;
- }
- }
- return true;
- }
- }
- }
- }
|