using System; using System.Collections; using System.Data; using Zhaizj.Framework.Data; using Zhaizj.Framework.Members.Interface; using Zhaizj.Framework.Web; using Zhaizj.Framework.ORM.Utils; using Zhaizj.Framework.ORM.Caching; namespace Zhaizj.Framework.ORM.Operation { internal class FindByIdOperation { private static readonly ILog logger = LogManager.GetLogger( typeof( FindByIdOperation ) ); public static IEntity FindById( int id, ObjectInfo state ) { if (id < 0) return null; IEntity result = null; if (state.IsFindChild) result = findByIdFromChild( id, state.EntityInfo ); if (result != null) return result; if (state.Includer.EntityPropertyList == null) state.Includer.IncludeAll(); return findById_Private( id, state ); } private static IEntity findById_Private( int id, ObjectInfo state ) { if (id < 0) return null; IEntity result = null; SqlBuilder sh = new SqlBuilder( state.EntityInfo ); processIncluder( state.Includer ); String sql = sh.GetFindById( id, state.Includer.SelectedProperty ); IDbCommand cmd = DataFactory.GetCommand( sql, DbContext.getConnection( state.EntityInfo ) ); IList list = new ArrayList(); IDataReader rd = null; try { rd = cmd.ExecuteReader(); while (rd.Read()) { list.Add( FillUtil.Populate( rd, state ) ); } } catch (Exception ex) { logger.Error( ex.Message ); logger.Error( ex.StackTrace ); throw ex; } finally { OrmHelper.CloseDataReader( rd ); } if (list.Count > 0) result = list[0] as IEntity; result = setEntityProperty( result, id, state ); return result; } // TODO: performance private static IEntity findByIdFromChild( int id, EntityInfo entityInfo ) { foreach (EntityInfo ei in entityInfo.ChildEntityList) { IEntity result = ObjectDB.FindById( id, new ObjectInfo( ei ) ); if (result != null) return result; } return null; } // select is prior to include private static void processIncluder( Includer includer ) { if (strUtil.IsNullOrEmpty( includer.SelectedProperty )) return; if (includer.SelectedProperty.Equals( "*" )) includer.IncludeAll(); else includer.Include( SqlBuilder.GetIncludeProperty( includer.SelectedProperty ) ); } private static IEntity setEntityProperty( IEntity obj, int id, ObjectInfo state ) { if (obj == null) return null; IList entityPropertyList = state.EntityInfo.EntityPropertyList; foreach (EntityPropertyInfo ep in entityPropertyList) { if (!isPropertyInIncluder( ep, state.Includer.EntityPropertyList )) continue; IEntity propertyValue = obj.get( ep.Name ) as IEntity; if (propertyValue == null) continue; int pid = propertyValue.Id; if (pid <= 0) continue; IEntity cachedValue = ObjectPool.FindOne( ep.Type, pid ); if (cachedValue == null) { propertyValue = ObjectDB.FindById( pid, new ObjectInfo( ep.Type ) ); ObjectPool.Add( propertyValue ); } else { propertyValue = cachedValue; } ValueSetter.setEntityByCheckNull( obj, ep, propertyValue, pid ); } return obj; } private static Boolean isPropertyInIncluder( EntityPropertyInfo p, IList _includeEntityPropertyList ) { if (_includeEntityPropertyList == null) return false; if (_includeEntityPropertyList.Count == 0) return false; foreach (EntityPropertyInfo _include_ep in _includeEntityPropertyList) { if (_include_ep.Name.Equals( p.Name )) return true; } return false; } } }