Example #1
0
        private void GenerateSelect()
        {
            this._sql.AppendLine("SELECT");

            //生成第一个直接查询的表的所有列
            var rdp = RdbDataProvider.Get(this._directlyQueryRepository);
            var directlyQueryTableAlias   = this.GetTableAlias(rdp.DbTable.Name);
            var directlyQueryTableColumns = new SQLColumnsGenerator(this._directlyQueryRepository)
                                            .GetReadableColumnsSql(directlyQueryTableAlias);

            this._sql.Append(directlyQueryTableColumns).Append(',').AppendLine();

            //依次添加其它关系表的所有列
            var items = this._aggregateInfo.Items;

            foreach (var item in items)
            {
                var tableName  = RdbDataProvider.Get(item.PropertyEntityRepository).DbTable.Name;
                var tableAlias = GetTableAlias(tableName);
                var columns    = new SQLColumnsGenerator(item.PropertyEntityRepository);
                var sqlColumns = columns.GetReadableColumnsSql(tableAlias);

                this._sql.Append(sqlColumns);
                if (item != items.Last.Value)
                {
                    this._sql.Append(',');
                }
                this._sql.AppendLine();
            }
        }
Example #2
0
        public RdbTable CreateRdbTable(IRepositoryInternal repo)
        {
            RdbTable table = null;

            var provider = RdbDataProvider.Get(repo).DbSetting.ProviderName;

            table = this.CreateRdbTableCore(repo, provider);

            table.IdentifierProvider = DbMigrationProviderFactory.GetIdentifierProvider(provider);
            table.DbTypeConverter    = DbMigrationProviderFactory.GetDbTypeConverter(provider);

            var em = repo.EntityMeta;

            foreach (var columnInfo in table.Info.Columns)
            {
                var epm = em.Property(columnInfo.Property);
                if (epm == null)
                {
                    throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", table.Info.EntityType.FullName, columnInfo.Property.Name));
                }

                var column = table.CreateColumn(columnInfo);

                table.Add(column);
            }

            return(table);
        }
Example #3
0
        private void GenerateWhere()
        {
            if (this._whereCondition != null)
            {
                //把 whereCondition 中的所有表名都进行替换。
                this._sql.Append("WHERE ");
                string condition = this._whereCondition;
                foreach (var kv in this._tableAlias)
                {
                    condition = condition.Replace(kv.Key + '.', kv.Value + '.');
                }
                this._sql.AppendLine(condition);
            }
            else if (this._directlyQueryRepository.EntityMeta.EntityCategory == EntityCategory.Child)
            {
                this._sql.Append("WHERE ");

                var parentProperty   = this._directlyQueryRepository.FindParentPropertyInfo(true);
                var refIdProperty    = (parentProperty.ManagedProperty as IRefEntityProperty).RefIdProperty;
                var rootTypeFKColumn = refIdProperty.Name;//属性名就是列名

                var dqTableName  = RdbDataProvider.Get(this._directlyQueryRepository).DbTable.Name;
                var dqTableAlias = this.GetTableAlias(dqTableName);
                this._sql.Append(dqTableAlias).Append('.').Append(rootTypeFKColumn)
                .AppendLine(" = {0}");
            }
        }
Example #4
0
        /// <summary>
        /// 通过 IQuery 对象来查询数据表。
        /// </summary>
        /// <param name="query">查询条件。</param>
        /// <param name="paging">分页信息。</param>
        /// <returns></returns>
        public override LiteDataTable QueryTable(IQuery query, PagingInfo paging = null)
        {
            var generator = RdbDataProvider.Get(this.Repo).DbTable.CreateSqlGenerator();

            generator.Generate(query as SqlNode);
            var sql = generator.Sql;

            return(this.QueryTable(sql, paging));
        }
Example #5
0
        /// <summary>
        /// 子类重写此方法,查询从持久层加载表格的具体实现。
        /// </summary>
        /// <param name="args">The arguments.</param>
        protected virtual void QueryTableCore(TableQueryArgs args)
        {
            var dp = RdbDataProvider.Get(this.Repo);

            using (var dba = dp.CreateDbAccesser())
            {
                dp.DbTable.QueryTable(dba, args);
            }
        }
Example #6
0
        /// <summary>
        /// 子类重写此方法,查询从持久层加载列表的具体实现。
        /// </summary>
        /// <param name="args">The arguments.</param>
        /// <param name="entityList">The entity list.</param>
        protected virtual void QueryListCore(SqlQueryArgs args, EntityList entityList)
        {
            var dataProvider = RdbDataProvider.Get(Repo);

            using (var dba = dataProvider.CreateDbAccesser())
            {
                //访问数据库
                if (args.Filter != null)
                {
                    #region 内存过滤式加载

                    if (!PagingInfo.IsNullOrEmpty(args.PagingInfo))
                    {
                        throw new NotSupportedException("使用内存过滤器的同时,不支持提供分页参数。");
                    }

                    args.EntityType = Repo.EntityType;
                    args.MemoryList = new List <Entity>();
                    dataProvider.DbTable.QueryList(dba, args);
                    this.LoadByFilter(args);

                    #endregion
                }
                else
                {
                    if (args.FetchType == FetchType.Count)
                    {
                        #region 查询 Count

                        var value = dba.QueryValue(args.FormattedSql, args.Parameters);
                        var count = RdbTable.ConvertCount(value);
                        entityList.SetTotalCount(count);

                        #endregion
                    }
                    else
                    {
                        //是否需要为 PagingInfo 设置统计值。
                        var pagingInfoCount = !PagingInfo.IsNullOrEmpty(args.PagingInfo) && args.PagingInfo.IsNeedCount;

                        //如果 pagingInfoCount 为真,则在访问数据库时,会设置好 PagingInfo 的总行数。
                        args.EntityType = Repo.EntityType;
                        dataProvider.DbTable.QueryList(dba, args);

                        //最后,还需要设置列表的 TotalCount。
                        if (pagingInfoCount)
                        {
                            entityList.SetTotalCount(args.PagingInfo.TotalCount);
                        }
                    }
                }
            }
        }
Example #7
0
        /// <summary>
        /// 子类重写此方法,查询从持久层加载列表的具体实现。
        /// </summary>
        /// <param name="args">The arguments.</param>
        /// <param name="entityList">The entity list.</param>
        /// <exception cref="System.NotSupportedException">使用内存过滤器的同时,不支持提供分页参数。</exception>
        protected override void QueryListCore(EntityQueryArgs args, EntityList entityList)
        {
            var dp = RdbDataProvider.Get(this.Repo);

            using (var dba = dp.CreateDbAccesser())
            {
                //以下代码,开始访问数据库查询数据。
                var dbTable = dp.DbTable;
                if (args.Filter != null)
                {
                    #region 内存过滤式加载

                    if (!PagingInfo.IsNullOrEmpty(args.PagingInfo))
                    {
                        throw new NotSupportedException("使用内存过滤器的同时,不支持提供分页参数。");
                    }

                    args.MemoryList = new List <Entity>();
                    dbTable.QueryList(dba, args);
                    this.LoadByFilter(args);

                    #endregion
                }
                else
                {
                    if (args.FetchType == FetchType.Count)
                    {
                        #region 查询 Count

                        var count = dbTable.Count(dba, args.Query);
                        entityList.SetTotalCount(count);

                        #endregion
                    }
                    else
                    {
                        //是否需要为 PagingInfo 设置统计值。
                        var pi = args.PagingInfo;
                        var pagingInfoCount = !PagingInfo.IsNullOrEmpty(pi) && pi.IsNeedCount;

                        //如果 pagingInfoCount 为真,则在访问数据库时,会设置好 PagingInfo 的总行数。
                        dbTable.QueryList(dba, args);

                        //最后,还需要设置列表的 TotalCount。
                        if (pagingInfoCount)
                        {
                            entityList.SetTotalCount(pi.TotalCount);
                        }
                    }
                }
            }
        }
Example #8
0
        private void GenerateOuterJoin()
        {
            //依次添加其它关系表的关系约束
            var tmp = this._aggregateInfo.Items.First;

            do
            {
                var item = tmp.Value;

                //主键表和外键表的寻找有所不同:
                //如果是子对象加载类型,则分别是父表和子表
                //如果是引用对象加载类型,则主键表应该是被引用实体表
                RdbTable pkTable = null;
                RdbTable fkTable = null;
                string   fkName  = null;
                if (item.LoadType == AggregateLoadType.Children)
                {
                    pkTable = RdbDataProvider.Get(item.OwnerRepository).DbTable;
                    fkTable = RdbDataProvider.Get(item.PropertyEntityRepository).DbTable;
                    var parentProperty = item.PropertyEntityRepository.FindParentPropertyInfo(true);
                    var refIdProperty  = (parentProperty.ManagedProperty as IRefEntityProperty).RefIdProperty;
                    fkName = refIdProperty.Name;
                }
                else
                {
                    pkTable = RdbDataProvider.Get(item.PropertyEntityRepository).DbTable;
                    fkTable = RdbDataProvider.Get(item.OwnerRepository).DbTable;
                    fkName  = item.PropertyMeta.Name;
                }

                //当前的关系表的查找方法是固定的,就是属性实体。
                string propertyTableName = RdbDataProvider.Get(item.PropertyEntityRepository).DbTable.Name;

                //表所对应的别名
                string propertyTableAlias = this.GetTableAlias(propertyTableName);
                string pkTableAlias       = this.GetTableAlias(pkTable.Name);
                string fkTableAlias       = this.GetTableAlias(fkTable.Name);

                //组装SQL中的关系表
                this._sql.Append("    LEFT OUTER JOIN ").Append(propertyTableName)
                .Append(" ").Append(propertyTableAlias);

                //组装SQL中的关系表的Join条件。
                this._sql.Append(" ON ").Append(fkTableAlias).Append('.').Append(fkName)
                .Append(" = ").Append(pkTableAlias).Append('.').AppendLine(pkTable.PKColumn.Name);

                tmp = tmp.Next;
            } while (tmp != null);
        }
Example #9
0
        /// <summary>
        /// 为某个指定的仓库对象构造一个 DbTable
        /// </summary>
        /// <param name="repo"></param>
        /// <returns></returns>
        internal static RdbTable CreateORMTable(IRepositoryInternal repo)
        {
            RdbTable table = null;

            var provider = RdbDataProvider.Get(repo).DbSetting.ProviderName;

            switch (provider)
            {
            case DbSetting.Provider_SqlClient:
                table = new SqlServerTable(repo);
                break;

            case DbSetting.Provider_SqlCe:
                table = new SqlCeTable(repo);
                break;

            case DbSetting.Provider_MySql:
                table = new MySqlTable(repo);
                break;

            default:
                if (DbConnectionSchema.IsOracleProvider(provider))
                {
                    table = new OracleTable(repo);
                    break;
                }
                throw new NotSupportedException();
            }

            table.IdentifierProvider = DbMigrationProviderFactory.GetIdentifierProvider(provider);
            table.DbTypeConverter    = DbMigrationProviderFactory.GetDbTypeConverter(provider);

            var em = repo.EntityMeta;

            foreach (var columnInfo in table.Info.Columns)
            {
                var epm = em.Property(columnInfo.Property);
                if (epm == null)
                {
                    throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", table.Info.Class.FullName, columnInfo.Property.Name));
                }

                var column = table.CreateColumn(columnInfo);

                table.Add(column);
            }

            return(table);
        }
Example #10
0
        /// <summary>
        /// 通过聚合SQL加载整个聚合对象列表。
        /// </summary>
        /// <param name="list">The list.</param>
        /// <param name="sql">The SQL.</param>
        internal void Query(EntityList list, string sql)
        {
            IDataTable dataTable = null;

            var repo = this._aggregateInfo.Items.First.Value.OwnerRepository;

            using (var db = RdbDataProvider.Get(repo).CreateDbAccesser())
            {
                var table = db.RawAccesser.QueryDataTable(sql, CommandType.Text);

                dataTable = new RawTable(table);
            }

            //使用dataTable中的数据 和 AggregateDescriptor 中的描述信息,读取整个聚合列表。
            this.ReadFromTable(list, dataTable, this._aggregateInfo.Items.First);
        }
Example #11
0
        private void GenerateFrom()
        {
            //From “第一个直接查询的表”
            var tableName  = RdbDataProvider.Get(this._directlyQueryRepository).DbTable.Name;
            var tableAlias = this.GetTableAlias(tableName);

            this._sql.Append("FROM ").Append(tableName).Append(" ").AppendLine(tableAlias);

            //如果有joinFilterCondition,则添加上。
            if (this._joinFilterCondition != null)
            {
                var joinCondition = this._joinFilterCondition.Replace(tableName + '.', tableAlias + '.');

                this._sql.Append("    ").AppendLine(joinCondition);
            }
        }
Example #12
0
            /// <summary>
            /// 这个方法把table中的数据全部读取并转换为对象存入对象列表中。
            ///
            /// 算法简介:
            /// 由于子对象的数据都是存储在这个IGTable中,所以每一个TEntity可能对应多个行,
            /// 每一行数据其实就是一个子对象的数据,而TEntity的属性值是重复的。
            /// 所以这里找到每个TEntity对应的第一行和最后一行,把它封装为一个子表格,传给子对象集合进行加载。
            /// 这样的设计是为了实现重用这个方法:集合加载IGTable中的数据。
            /// </summary>
            /// <param name="list">转换的对象存入这个列表中</param>
            /// <param name="table">表格数据,数据类型于以下形式:
            /// TableA  TableB  TableC  TableD...
            /// a1      b1      c1
            /// a1      b1      c2
            /// a2      b2      NULL
            /// a3      NULL    NULL
            /// ...</param>
            /// <param name="relationLoader">为每个TEntity调用此方法,从IGTable中加载它对应的孩子对象。
            /// 加载完成后的对象会被加入到list中,所以此方法有可能返回一个全新的TEntity。</param>
            public static void ReadFromTable(EntityList list, IDataTable table, Action <Entity, IDataTable> relationLoader)
            {
                var    entityType = list.EntityType;
                var    repo       = RepositoryFactoryHost.Factory.FindByEntity(entityType);
                string idName     = RdbDataProvider.Get(repo).SQLColumnsGenerator.GetReadableIdColumnSql();

                object lastId = null;
                //每个TEntity对象对应的第一行数据
                int startRow = 0;

                for (int i = 0, c = table.Count; i < c; i++)
                {
                    var row = table[i];

                    var    objId = row[idName];
                    object id    = objId != DBNull.Value ? objId : null;

                    //如果 id 改变,表示已经进入到下一个 TEntity 对象的开始行了。
                    if (id != lastId)
                    {
                        //不是第一次 或者 全是NULL值
                        if (lastId != null)
                        {
                            //前一行就是最后一行。
                            int endRow = i - 1;

                            Entity item = CreateEntity(entityType, table, startRow, endRow, relationLoader);

                            list.Add(item);
                        }

                        //重置 startRow 为下一个 TEntity
                        startRow = i;
                    }

                    lastId = id;
                }

                //加入最后一个 Entity
                if (lastId != null)
                {
                    Entity lastEntity = CreateEntity(entityType, table, startRow, table.Count - 1, relationLoader);
                    list.Add(lastEntity);
                }
            }
Example #13
0
            /// <summary>
            /// 把 table 从 startRow 到 endRow 之间的数据,都转换为一个 TEntity 并返回。
            /// </summary>
            /// <param name="entityType">Type of the entity.</param>
            /// <param name="table">The table.</param>
            /// <param name="startRow">The start row.</param>
            /// <param name="endRow">The end row.</param>
            /// <param name="relationLoader">The relation loader.</param>
            /// <returns></returns>
            private static Entity CreateEntity(Type entityType, IDataTable table, int startRow, int endRow, Action <Entity, IDataTable> relationLoader)
            {
                //新的TEntity
                var repo   = RepositoryFactoryHost.Factory.FindByEntity(entityType);
                var entity = RdbDataProvider.Get(repo).SQLColumnsGenerator.ReadDataDirectly(table[startRow]);

                if (entity == null)
                {
                    throw new InvalidProgramException("id不为空,对象也不应该为空。");
                }

                var childTable = new SubTable(table, startRow, endRow);

                if (relationLoader != null)
                {
                    relationLoader(entity, childTable);
                }
                return(entity);
            }
Example #14
0
        /// <summary>
        /// 为某个指定的仓库对象构造一个 DbTable
        /// </summary>
        /// <param name="repo"></param>
        /// <returns></returns>
        internal static IPersistanceTableInfo CreateTableInfo(IRepositoryInternal repo)
        {
            var em = repo.EntityMeta;

            if (em.TableMeta == null)
            {
                throw new ORMException(string.Format("类型 {0} 没有映射数据库,无法为其创造 ORM 运行时对象。", em.EntityType.FullName));
            }

            var dbSetting          = RdbDataProvider.Get(repo).DbSetting;
            var identifierProvider = DbMigrationProviderFactory.GetIdentifierProvider(dbSetting.ProviderName);
            var dbTypeConverter    = DbMigrationProviderFactory.GetDbTypeConverter(dbSetting.ProviderName);

            var name = identifierProvider.Prepare(repo.EntityMeta.TableMeta.TableName);
            var res  = new PersistanceTableInfo(name, repo);

            ProcessManagedProperties(em.EntityType, res, em, identifierProvider, dbTypeConverter);

            return(res);
        }
Example #15
0
        /// <summary>
        /// 为某个指定的仓库对象构造一个 DbTable
        /// </summary>
        /// <param name="repo"></param>
        /// <returns></returns>
        internal static RdbTable CreateORMTable(IRepositoryInternal repo)
        {
            RdbTable table = null;

            switch (RdbDataProvider.Get(repo).DbSetting.ProviderName)
            {
            case DbSetting.Provider_SqlClient:
                table = new SqlTable(repo);
                break;

            case DbSetting.Provider_SqlCe:
                table = new SqlCeTable(repo);
                break;

            case DbSetting.Provider_Oracle:
                table = new OracleTable(repo);
                break;

            default:
                throw new NotSupportedException();
            }

            var em = repo.EntityMeta;

            foreach (var columnInfo in table.Info.Columns)
            {
                //生成 ManagedPropertyBridge
                var epm = em.Property(columnInfo.Property);
                if (epm == null)
                {
                    throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", table.Info.Class.FullName, columnInfo.Property.Name));
                }

                var column = table.CreateColumn(columnInfo);
                table.Add(column);
            }

            return(table);
        }
Example #16
0
        private void GenerateOrderBy()
        {
            var table = RdbDataProvider.Get(this._directlyQueryRepository).DbTable;
            var directlyQueryTableAlias = this.GetTableAlias(table.Name);

            this._sql.Append("ORDER BY ").Append(directlyQueryTableAlias)
            .Append('.').Append(table.PKColumn.Name);

            var tmp = this._aggregateInfo.Items.First;

            do
            {
                var item = tmp.Value;

                var propertyTable      = RdbDataProvider.Get(item.PropertyEntityRepository).DbTable;
                var propertyTableAlias = this.GetTableAlias(propertyTable.Name);

                this._sql.Append(", ").Append(propertyTableAlias).Append('.').Append(propertyTable.PKColumn.Name);

                tmp = tmp.Next;
            } while (tmp != null);
        }
Example #17
0
 public RdbRedundanciesUpdater(RdbDataProvider dataProvider)
     : base(dataProvider)
 {
     _dataProvider = dataProvider;
 }
Example #18
0
 private RdbTable GetTableInfo()
 {
     return(RdbDataProvider.Get(this._repository).DbTable);
 }
Example #19
0
 public RdbRedundanciesUpdater(RdbDataProvider dataProvider)
     : base(dataProvider)
 {
     _dataProvider = dataProvider;
 }
Example #20
0
        protected internal override void Init(RepositoryDataProvider dataProvider)
        {
            base.Init(dataProvider);

            _dataProvider = dataProvider as RdbDataProvider;
        }
Example #21
0
        /// <summary>
        /// 根据配置文件,构造一个数据库访问器。
        /// </summary>
        /// <param name="repository">实体仓库所代表的数据库配置。</param>
        /// <returns></returns>
        public static IDbAccesser Create(IRepository repository)
        {
            var setting = RdbDataProvider.Get(repository).DbSetting;

            return(new ManagedConnectionDbAccesser(setting));
        }
Example #22
0
        protected internal override void Init(RepositoryDataProvider dataProvider)
        {
            base.Init(dataProvider);

            _dataProvider = dataProvider as RdbDataProvider;
        }
Example #23
0
        /// <summary>
        /// 获取该实体对应的 ORM 运行时对象。
        ///
        /// 如果该实体没有对应的实体元数据或者该实体没有被配置为映射数据库,
        /// 则本方法则无法创建对应的 ORM 运行时,此时会返回 null。
        /// </summary>
        /// <param name="entityType">实体类型</param>
        /// <returns></returns>
        internal static RdbTable TableFor(Type entityType)
        {
            var repo = RepositoryFactoryHost.Factory.FindByEntity(entityType);

            return(RdbDataProvider.Get(repo).DbTable);
        }