Mercurial > pub > bltoolkit
view Extensions/JointureAddOn/DataAccess/FullSqlQueryBase.cs @ 9:1e85f66cf767 default tip
update bltoolkit
author | nickolay |
---|---|
date | Thu, 05 Apr 2018 20:53:26 +0300 |
parents | f990fcb411a9 |
children |
line wrap: on
line source
using System; using System.Collections; using System.Linq; using System.Reflection; using System.Text; using BLToolkit.Aspects; using BLToolkit.Data; using BLToolkit.Data.DataProvider; using BLToolkit.Mapping; using BLToolkit.TypeBuilder; namespace BLToolkit.DataAccess { public abstract class FullSqlQueryBase : SqlQueryBase { private readonly bool _ignoreLazyLoad; #region Constructors protected FullSqlQueryBase(DbManager dbManager, bool ignoreLazyLoad = false, MappingOrder mappingOrder = MappingOrder.ByColumnIndex) : base(dbManager) { dbManager.MappingSchema = new FullMappingSchema(dbManager, mappingOrder: mappingOrder); _ignoreLazyLoad = ignoreLazyLoad; } #endregion #region Overrides [NoInterception] protected override SqlQueryInfo CreateSqlText(DbManager db, Type type, string actionName) { switch (actionName) { case "SelectByKey": return CreateSelectFullByKeySqlText(db, type); case "SelectAll": return CreateSelectAllFullSqlText(db, type); default: return base.CreateSqlText(db, type, actionName); } } protected override void AppendTableName(StringBuilder sb, DbManager db, Type type) { var database = GetDatabaseName(type); var owner = GetOwnerName(type); var name = base.GetTableName(type); db.DataProvider.CreateSqlProvider().BuildTableName(sb, database == null ? null : db.DataProvider.Convert(database, ConvertType.NameToDatabase).ToString(), owner == null ? null : db.DataProvider.Convert(owner, ConvertType.NameToOwner).ToString(), name == null ? null : db.DataProvider.Convert(name, ConvertType.NameToQueryTable).ToString()); //TODO Override OracleSqlProvider in order to avoid this mess... string alias = GetTableName(type); sb.Append(" " + alias); sb.AppendLine(); } protected override string GetTableName(Type type) { //bool isSet; //return MappingSchema.MetadataProvider.GetTableName(type, Extensions, out isSet); return type.Name; } #endregion private SqlQueryInfo CreateSelectAllFullSqlText(DbManager db, Type type) { var sb = new StringBuilder(); var query = new FullSqlQueryInfo(); sb.Append("SELECT\n"); var mainMapper = (FullObjectMapper)db.MappingSchema.GetObjectMapper(type); ; BuildSelectSQL(mainMapper, sb, db); sb.Remove(sb.Length - 2, 1); sb.Append("FROM\n\t"); AppendTableName(sb, db, type); AppendJoinTableName(sb, db, type); query.QueryText = sb.ToString(); return query; } private SqlQueryInfo CreateSelectFullByKeySqlText(DbManager db, Type type) { var sb = new StringBuilder(); var query = new FullSqlQueryInfo(); sb.Append("SELECT\n"); var mainMapper = (FullObjectMapper)db.MappingSchema.GetObjectMapper(type); BuildSelectSQL(mainMapper, sb, db); sb.Remove(sb.Length - 2, 1); sb.Append("FROM\n\t"); AppendTableName(sb, db, type); AppendJoinTableName(sb, db, type); AddWherePK(db, query, sb, -1, mainMapper); query.QueryText = sb.ToString(); return query; } private void BuildSelectSQL(IPropertiesMapping mapper, StringBuilder sb, DbManager db) { foreach (IMapper mapField in mapper.PropertiesMapping) { if (mapField is ValueMapper) sb.AppendFormat("\t{0}.{1},\n", ((IObjectMapper)mapper).PropertyType.Name, db.DataProvider.Convert(((ValueMapper)mapField).ColumnName, ConvertType.NameToQueryField)); else if (mapField is IPropertiesMapping) { var propertiesMapping = (IPropertiesMapping)mapField; var cel = propertiesMapping.ParentMapping; while (cel != null) { // To avoid recursion dont take in account types already loaded. if (((IMapper)cel).PropertyType == mapField.PropertyType) continue; cel = cel.ParentMapping; } var objectMapper = (IObjectMapper)mapField; if (!objectMapper.IsLazy) BuildSelectSQL(propertiesMapping, sb, db); } else throw new NotImplementedException(mapField.GetType() + " is not yet implemented."); } } private void AppendJoinTableName(StringBuilder sb, DbManager db, Type type) { string parentName = GetTableName(type); foreach (PropertyInfo prop in type.GetProperties()) { bool isCollection = prop.PropertyType.GetInterfaces().ToList().Contains(typeof(IList)); Type listElementType = null; if (isCollection) { listElementType = FullMappingSchema.GetGenericType(prop.PropertyType); } if (!_ignoreLazyLoad) { object[] lazy = prop.GetCustomAttributes(typeof(LazyInstanceAttribute), true); if (lazy.Length > 0) { if (((LazyInstanceAttribute)lazy[0]).IsLazy) { continue; } } } object[] attribs = prop.GetCustomAttributes(typeof(AssociationAttribute), true); if (attribs.Length > 0) { var assocAttrib = (AssociationAttribute)attribs[0]; PropertyInfo parentField = type.GetProperty(assocAttrib.ThisKey); PropertyInfo childField = prop.PropertyType.GetProperty(assocAttrib.OtherKey); if (isCollection) { childField = listElementType.GetProperty(assocAttrib.OtherKey); //FullMappingSchema.GetColumnFromProperty(listElementType, associationAttribute.OtherKey); } object[] parentFieldAttributes = parentField.GetCustomAttributes(typeof(MapFieldAttribute), true); string parentDbField = parentFieldAttributes.Length > 0 ? ((MapFieldAttribute)parentFieldAttributes[0]).MapName : assocAttrib.ThisKey; object[] childFieldAttributes = childField.GetCustomAttributes(typeof(MapFieldAttribute), true); string childDbField = childFieldAttributes.Length > 0 ? ((MapFieldAttribute)childFieldAttributes[0]).MapName : assocAttrib.OtherKey; string childDatabase = isCollection ? GetDatabaseName(listElementType) : GetDatabaseName(prop.PropertyType); string childOwner = isCollection ? base.GetOwnerName(listElementType) : base.GetOwnerName(prop.PropertyType); string childName = isCollection ? base.GetTableName(listElementType) : base.GetTableName(prop.PropertyType); string childAlias = isCollection ? GetTableName(listElementType) : GetTableName(prop.PropertyType); StringBuilder childFullName = db.DataProvider.CreateSqlProvider().BuildTableName( new StringBuilder(), childDatabase == null ? null : db.DataProvider.Convert(childDatabase, ConvertType.NameToDatabase).ToString(), childOwner == null ? null : db.DataProvider.Convert(childOwner, ConvertType.NameToOwner).ToString(), childName == null ? null : db.DataProvider.Convert(childName, ConvertType.NameToQueryTable).ToString()); sb.AppendFormat("\tINNER JOIN {0} {1} ON {2}.{3}={4}.{5}\n", childFullName, childAlias, parentName, parentDbField, childAlias, childDbField ); AppendJoinTableName(sb, db, isCollection ? listElementType : prop.PropertyType); } } sb.AppendLine(); //SELECT // ARTIST2.ID_ARTIST, // ARTIST2.ARTIST, // TRACK.ID_TRACK, // TRACK.TRACK, // TRACK.ID_ARTIST, // ARTIST.ID_ARTIST, // ARTIST.ARTIST //FROM // PITAFR01.ARTIST ARTIST2 // INNER JOIN PITAFR01.TRACK TRACK ON ARTIST2.ID_ARTIST=TRACK.ID_ARTIST // INNER JOIN PITAFR01.ARTIST ARTIST ON TRACK.ID_ARTIST=ARTIST.ID_ARTIST //WHERE // ARTIST2.ID_ARTIST = 2566 } private void AddWherePK(DbManager db, SqlQueryInfo query, StringBuilder sb, int nParameter, FullObjectMapper mapper) { sb.Append("WHERE\n"); foreach (IMapper mm in mapper.PropertiesMapping) { if (mm is ValueMapper && mm.DataReaderIndex == mapper.DataReaderIndex) { var valueMapper = (ValueMapper)mm; string tableAlias = mapper.PropertyType.Name; //mm.Name = ID_TRACK SqlQueryParameterInfo p = query.AddParameter( db.DataProvider.Convert(valueMapper.ColumnName + "_W", ConvertType.NameToQueryParameter). ToString(), valueMapper.ColumnName); sb.AppendFormat("\t{0}.{1} = ", tableAlias, db.DataProvider.Convert(p.FieldName, ConvertType.NameToQueryField)); if (nParameter < 0) sb.AppendFormat("{0} AND\n", p.ParameterName); else sb.AppendFormat("{{{0}}} AND\n", nParameter++); } } sb.Remove(sb.Length - 5, 5); } } }