/// <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); }
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); }
/// <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; }
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); }
/// <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); } } } } }
/// <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); }
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); }
/// <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); }
internal static FormattedSql AppendQuoteName(this FormattedSql sql, RdbTable table) { table.AppendQuote(sql.InnerWriter, table.Name); return(sql); }
internal static TextWriter AppendQuote(this TextWriter sql, RdbTable table, string identifier) { table.AppendQuote(sql, identifier); return(sql); }
internal RdbColumn(RdbTable table, IPersistanceColumnInfo columnInfo) { _table = table; _columnInfo = columnInfo; }
internal RdbColumn(RdbTable table, IRdbColumnInfo columnInfo) { _table = table; _columnInfo = columnInfo; }
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; }
internal static TextWriter AppendQuote(this TextWriter sql, RdbTable table, string identifier) { table.AppendQuote(sql, identifier); return sql; }
/// <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); //} }
internal static FormattedSql AppendQuote(this FormattedSql sql, RdbTable table, string identifier) { table.AppendQuote(sql.InnerWriter, identifier); return(sql); }
internal static FormattedSql AppendQuote(this FormattedSql sql, RdbTable table, string identifier) { table.AppendQuote(sql.InnerWriter, identifier); return sql; }
internal static FormattedSql AppendQuoteName(this FormattedSql sql, RdbTable table) { table.AppendQuote(sql.InnerWriter, table.Name); return sql; }
internal static TextWriter AppendQuoteName(this TextWriter sql, RdbTable table) { table.AppendQuote(sql, table.Name); return sql; }
/// <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(""); }
internal static TextWriter AppendQuoteName(this TextWriter sql, RdbTable table) { table.AppendQuote(sql, table.Name); return(sql); }
/// <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(); }