Пример #1
0
        /// <summary>
        /// 通过托管属性及其对应的实体类型,并通过可用的缓存列表,查找对应的 DbTable。
        /// </summary>
        /// <param name="property"></param>
        /// <param name="propertyOwner"></param>
        /// <param name="tablesCache"></param>
        /// <returns></returns>
        internal static RdbTable GetPropertyTable(IManagedProperty property, Type propertyOwner, Dictionary <Type, RdbTable> tablesCache)
        {
            RdbTable result = null;

            if (propertyOwner == null)
            {
                propertyOwner = property.OwnerType;
            }

            if (!tablesCache.TryGetValue(propertyOwner, out result))
            {
                if (!propertyOwner.IsAbstract)
                {
                    result = RdbTableFinder.TableFor(propertyOwner);
                }

                if (result == null)
                {
                    ORMHelper.ThrowBasePropertyNotMappedException(property.Name, propertyOwner);
                }

                tablesCache.Add(propertyOwner, result);
            }

            return(result);
        }
Пример #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);
        }
Пример #3
0
        /// <summary>
        /// 为指定的实体列表构造一个批处理命令。
        /// </summary>
        /// <param name="entityList"></param>
        /// <param name="db"></param>
        /// <param name="table"></param>
        public BatchInsert(IList<Entity> entityList, SqlConnection db, RdbTable table)
        {
            if (entityList.Count < 1) throw new ArgumentOutOfRangeException();

            this._table = table;
            this._entityList = entityList;
            this._db = db;
        }
Пример #4
0
 public void GetSql(TextWriter sql, RdbTable table)
 {
     string name = table.Translate(this._property);
     string dir = _asc ? "ASC" : "DESC";
     sql.AppendQuoteName(table).Write('.');
     sql.AppendQuote(table, name);
     sql.Write(' ');
     sql.Write(dir);
 }
Пример #5
0
 public void GetSql(TextWriter sql, RdbTable table)
 {
     string name = table.Translate(this._property);
     string dir = _asc ? "ASC" : "DESC";
     sql.AppendQuoteName(table).Write('.');
     sql.AppendQuote(table, name);
     sql.Write(' ');
     sql.Write(dir);
 }
Пример #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);
                        }
                    }
                }
            }
        }
Пример #7
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);
        }
Пример #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);
        }
Пример #9
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);
        }
Пример #10
0
 internal static FormattedSql AppendQuoteName(this FormattedSql sql, RdbTable table)
 {
     table.AppendQuote(sql.InnerWriter, table.Name);
     return(sql);
 }
Пример #11
0
 internal static TextWriter AppendQuote(this TextWriter sql, RdbTable table, string identifier)
 {
     table.AppendQuote(sql, identifier);
     return(sql);
 }
Пример #12
0
 internal RdbColumn(RdbTable table, IPersistanceColumnInfo columnInfo)
 {
     _table = table;
     _columnInfo = columnInfo;
 }
Пример #13
0
 internal RdbColumn(RdbTable table, IRdbColumnInfo columnInfo)
 {
     _table      = table;
     _columnInfo = columnInfo;
 }
Пример #14
0
        private DataTable ToDataTable(RdbTable meta, IList<Entity> list, bool isUpdating = false)
        {
            //创建表格式
            var table = new DataTable();
            var columns = meta.Columns;
            foreach (var column in columns)
            {
                var dataType = TypeHelper.IgnoreNullable(column.Info.DataType);
                table.Columns.Add(new DataColumn(column.Name, dataType));
            }

            //从实体中读取数据
            var rows = table.Rows;
            for (int i = 0, c = list.Count; i < c; i++)
            {
                var entity = list[i];
                var row = table.NewRow();
                for (int j = 0, jc = columns.Count; j < jc; j++)
                {
                    var column = columns[j];
                    row[j] = column.ReadParameterValue(entity);
                }
                rows.Add(row);

                if (isUpdating)
                {
                    row.AcceptChanges();
                    row.SetModified();
                }
            }

            return table;
        }
Пример #15
0
 internal static TextWriter AppendQuote(this TextWriter sql, RdbTable table, string identifier)
 {
     table.AppendQuote(sql, identifier);
     return sql;
 }
Пример #16
0
        /// <summary>
        /// 设置DataTable到数据库中表的映射
        /// </summary>
        /// <param name="mappings">The mappings.</param>
        /// <param name="table">The table.</param>
        private void SetMappings(SqlBulkCopyColumnMappingCollection mappings, RdbTable table)
        {
            foreach (var column in table.Columns)
            {
                mappings.Add(column.Name, column.Name);
            }

            //暂留:通过查询的真实列名来实现 Mapping。
            //var sql = string.Format("SELECT TOP 0 * FROM [{0}]", _table.Name);
            //var dbNames = new List<string>();
            //using (var reader = _meta.DBA.QueryDataReader(sql))
            //{
            //    for (int i = 0, c = reader.FieldCount; i < c; i++)
            //    {
            //        var name = reader.GetName(i);
            //        dbNames.Add(name);
            //    }
            //}
            //foreach (var column in _table.Columns)
            //{
            //    var correspondingDbName = dbNames.First(c => string.Compare(c, column.Name, true) == 0);
            //    mappings.Add(column.Name, correspondingDbName);
            //}
        }
Пример #17
0
 internal static FormattedSql AppendQuote(this FormattedSql sql, RdbTable table, string identifier)
 {
     table.AppendQuote(sql.InnerWriter, identifier);
     return(sql);
 }
Пример #18
0
 internal static FormattedSql AppendQuote(this FormattedSql sql, RdbTable table, string identifier)
 {
     table.AppendQuote(sql.InnerWriter, identifier);
     return sql;
 }
Пример #19
0
 internal static FormattedSql AppendQuoteName(this FormattedSql sql, RdbTable table)
 {
     table.AppendQuote(sql.InnerWriter, table.Name);
     return sql;
 }
Пример #20
0
 internal static TextWriter AppendQuoteName(this TextWriter sql, RdbTable table)
 {
     table.AppendQuote(sql, table.Name);
     return sql;
 }
Пример #21
0
        /// <summary>
        /// 获取指定大小批量的连续的 Id 号。返回第一个 Id 号的值。
        /// </summary>
        /// <param name="dba">The dba.</param>
        /// <param name="table">The table.</param>
        /// <param name="size">需要连续的多少个 Id 号。</param>
        /// <returns></returns>
        private static int GetBatchIDs(IDbAccesser dba, RdbTable table, int size)
        {
            /*********************** 代码块解释 *********************************
             * 算法解释:
             * 1.先查出当前最大的 ID 值;
             * 2.计算出所需要使用的区间的起始、终止值 [start,end];
             * 3.然后设置 IDENTITY 的种子值为终止值;
             * 4.由于上两步 SQL 执行过程中有可能其它线程使用了这个 IDENTITY 而造成 [start,end] 中的值被使用,
             * 所以需要对表中的数据进行检测,如果没有被使用,才把这些 ID 值返回。
             * 如果被使用了,则上述过程重来一次即可。
             *
             * IDENTITY 的操作方法:http://www.cnblogs.com/gaizai/archive/2013/04/23/3038318.html
            **********************************************************************/

            var tableName = table.Name;

            lock (_identityLock)
            {
                while (true)
                {
                    var currentValue = Convert.ToInt32(dba.QueryValue(string.Format("SELECT IDENT_CURRENT('{0}')", tableName)));
                    var start = currentValue + 1;
                    var end = start + size - 1;
                    dba.ExecuteText(string.Format("DBCC CHECKIDENT('{0}', RESEED, {1})", tableName, end));

                    var concurrency = dba.QueryValue(string.Format(
                        "SELECT 1 WHERE EXISTS (SELECT 1 FROM {0} WHERE {1} >= {2} AND {1} <= {3})",
                        tableName, table.IdentityColumn.Name, start, end
                        ));
                    if (concurrency == null) return start;
                }
            }

            throw new InvalidOperationException("");
        }
Пример #22
0
 internal static TextWriter AppendQuoteName(this TextWriter sql, RdbTable table)
 {
     table.AppendQuote(sql, table.Name);
     return(sql);
 }
Пример #23
0
 internal RdbColumn(RdbTable table, IPersistanceColumnInfo columnInfo)
 {
     _table      = table;
     _columnInfo = columnInfo;
 }
Пример #24
0
        /// <summary>
        /// 生成 Update 语句。
        /// 注意,此方法不会更新 LOB 字段。
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        private string GenerateUpdateSQL(RdbTable table)
        {
            //代码参考 RdbTable.GenerateUpdateSQL() 方法。

            var sql = new StringWriter();
            sql.Write("UPDATE ");
            sql.AppendQuoteName(table);
            sql.Write(" SET ");

            var updateLOB = this.UpdateLOB;
            bool comma = false;
            var columns = table.Columns;
            for (int i = 0, c = columns.Count; i < c; i++)
            {
                var column = columns[i];
                if (!column.Info.IsPrimaryKey && (updateLOB || !column.IsLOB))
                {
                    if (comma) { sql.Write(','); }
                    else { comma = true; }

                    sql.AppendQuote(table, column.Name).Write(" = @");
                    sql.Write(column.Name);
                }
            }

            sql.Write(" WHERE ");
            sql.AppendQuote(table, table.PKColumn.Name);
            sql.Write(" = @");
            sql.Write(table.PKColumn.Name);

            return sql.ToString();
        }