/// <summary> /// 获取实体 /// </summary> /// <param name="row">数据行</param> /// <param name="columns">列集合</param> /// <returns>数据表实体</returns> protected override T CreateEntity(DataRow row, DataColumnCollection columns) { T entity = new T(); PropertyInfo[] props = this._entityType.GetProperties(); foreach (PropertyInfo prop in props) { DatabaseColumnAtrribute attr = null; if (this._columns.TryGetValue(prop.Name, out attr) && attr != null) { DbType dbType = (attr.DbType.HasValue ? attr.DbType.Value : DbTypeHelper.InternalGetDbType(prop.PropertyType)); Object value; if (this.IsNullableType(prop.PropertyType)) { value = this.LoadNullableValue(row, columns, attr.ColumnName, dbType); } else { value = this.LoadValue(row, columns, attr.ColumnName, dbType); } prop.SetValue(entity, value, null); } } return(entity); }
public static bool Equals(Column a, Column b) { if (a.Table.Name.EqualsIgnoreCase(b.Table.Name) && a.Name.EqualsIgnoreCase(b.Name) && DbTypeHelper.IsCompatible(a.DataType, b.DataType) && //a.DataType == b.DataType && a.IsRequired == b.IsRequired && a.IsForeignKey == b.IsForeignKey && a.IsPrimaryKey == b.IsPrimaryKey ) { //判断外键是否相等 //暂时不考虑NeedDeleteCascade是否相同的问题 if (a.IsForeignKey && !a.ForeignConstraint.PKColumn.Table.Name.EqualsIgnoreCase(b.ForeignConstraint.PKColumn.Table.Name)) { return(false); } else { return(true); } } else { return(false); } }
/// <summary> /// 生成与 Sql 配套的参数列表。 /// </summary> /// <param name="meta">The meta.</param> /// <returns></returns> private IDbDataParameter[] GenerateUpdateParameters(EntityBatch meta) { var dba = meta.DBA.RawAccesser; var table = meta.Table; //把所有实体中所有属性的值读取到数组中,参数的值就是这个数组。 var updateLOB = this.UpdateLOB; var parameters = new List <IDbDataParameter>(); 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)) { var parameter = dba.ParameterFactory.CreateParameter(); parameter.ParameterName = '@' + column.Name; parameter.SourceColumn = column.Name;//额外地,需要设置 SourceColumn parameter.DbType = column.Info.ColumnMeta.DataType ?? DbTypeHelper.ConvertFromCLRType(column.Info.DataType); parameters.Add(parameter); } } //主键列放在最后。 var pkParameter = dba.ParameterFactory.CreateParameter(); pkParameter.ParameterName = '@' + table.PKColumn.Name; pkParameter.SourceColumn = table.PKColumn.Name; pkParameter.DbType = table.PKColumn.Info.ColumnMeta.DataType ?? DbTypeHelper.ConvertFromCLRType(table.PKColumn.Info.DataType); parameters.Add(pkParameter); return(parameters.ToArray()); }
public static DbType ConvertFromCLRType(Type clrType) { var value = DbTypeHelper.ConvertFromCLRType(clrType); if (value == DbType.Boolean) { value = DbType.String; } return(value); }
public void DMT_AlterColumn_DataType_AutoMigrate() { this.Test(destination => { }, result => { var table = result.FindTable("Task"); var column = table.FindColumn("XmlContent"); Assert.IsTrue(column != null); var p = DbSetting.FindOrCreate(UnitTestEntityRepositoryDataProvider.DbSettingName).ProviderName; Assert.IsTrue(DbTypeHelper.IsCompatible(column.DataType, DbType.Xml)); }); }
public void DMT_CreateColumn_Decimal() { this.Test(destination => { var taskTable = destination.FindTable("Task"); taskTable.AddColumn("TestingColumn", DbType.Decimal, isRequired: true); }, result => { var taskTable = result.FindTable("Task"); var c1 = taskTable.FindColumn("TestingColumn"); Assert.IsTrue(c1 != null && c1.IsRequired); Assert.IsTrue(DbTypeHelper.IsCompatible(c1.DataType, DbType.Decimal)); }); }
public void DMT_AlterColumn_DataType_NullStringToDouble() { this.Test(destination => { var taskTable = destination.FindTable("Task"); taskTable.Columns.Remove(taskTable.FindColumn("Name")); taskTable.AddColumn("Name", DbType.Double, isRequired: true); }, result => { var table = result.FindTable("Task"); var column = table.FindColumn("Name"); Assert.IsTrue(column != null); Assert.IsTrue(DbTypeHelper.IsCompatible(column.DataType, DbType.Double)); Assert.IsTrue(column.IsRequired); }); }
private static ColumnChanges Distinguish(Column oldColumn, Column newColumn) { //if (newColumn == null) throw new ArgumentNullException("newColumn"); //if (newColumn.Name.EqualsIgnoreCase(oldColumn.Name)) throw new InvalidOperationException("newColumn.Name.EqualsIgnoreCase(oldColumn.Name) must be false."); //if (newColumn.Table.Name.EqualsIgnoreCase(oldColumn.Table.Name)) throw new InvalidOperationException("newColumn.Table.Name.EqualsIgnoreCase(oldColumn.Table.Name) must be false."); ColumnChanges columnChanged = null; if (!Equals(newColumn, oldColumn)) { columnChanged = new ColumnChanges(oldColumn, newColumn, ChangeType.Modified); if (newColumn.IsRequired != oldColumn.IsRequired) { columnChanged.IsRequiredChanged = true; } if (newColumn.IsPrimaryKey != oldColumn.IsPrimaryKey) { columnChanged.IsPrimaryKeyChanged = true; } if (!DbTypeHelper.IsCompatible(newColumn.DataType, oldColumn.DataType)) { columnChanged.IsDbTypeChanged = true; } //ForeignRelationChangeType columnChanged.ForeignRelationChangeType = ChangeType.UnChanged; if (!newColumn.IsForeignKey && oldColumn.IsForeignKey) { columnChanged.ForeignRelationChangeType = ChangeType.Removed; } else if (newColumn.IsForeignKey && !oldColumn.IsForeignKey) { columnChanged.ForeignRelationChangeType = ChangeType.Added; } else if (newColumn.IsForeignKey && oldColumn.IsForeignKey) { if (!Equals(newColumn.ForeignConstraint, oldColumn.ForeignConstraint)) { columnChanged.ForeignRelationChangeType = ChangeType.Modified; } } } return(columnChanged); }
public void DMT_AlterColumn_DataType() { this.Test(destination => { var taskTable = destination.FindTable("Task"); taskTable.Columns.Remove(taskTable.FindColumn("Name")); taskTable.AddColumn("Name", DbType.Xml); }, result => { var table = result.FindTable("Task"); var column = table.FindColumn("Name"); Assert.IsTrue(column != null); var p = DbSetting.FindOrCreate(UnitTestEntityRepositoryDataProvider.DbSettingName).ProviderName; Assert.IsTrue(DbTypeHelper.IsCompatible(column.DataType, DbType.Xml)); }); }
public void DMT_CreateColumn_CLOB() { if (DbSetting.IsOracleProvider(UnitTest2EntityRepositoryDataProvider.DbSettingName)) { this.Test(destination => { var taskTable = destination.FindTable("Task"); taskTable.AddColumn("TestingColumn", DbType.String, "CLOB", isRequired: true); }, result => { var taskTable = result.FindTable("Task"); var c1 = taskTable.FindColumn("TestingColumn"); Assert.IsTrue(c1 != null && c1.IsRequired); Assert.IsTrue(DbTypeHelper.IsCompatible(c1.DataType, DbType.String)); }); } }
/// <summary> /// 根据实体类型创建表的描述信息,并添加到数据库中 /// </summary> /// <param name="em">The memory.</param> /// <exception cref="System.ArgumentNullException"></exception> /// <exception cref="System.InvalidOperationException">refMeta.ReferenceInfo == null</exception> private void BuildTable(EntityMeta em) { var tableMeta = em.TableMeta; //视图类不需要支持数据库迁移。 if (tableMeta.IsMappingView) { return; } var table = new Table(tableMeta.TableName, this.Database); //读取实体的注释 if (_readComment) { table.Comment = _commentFinder.TryFindComment(em.EntityType); } var metaProperties = em.EntityProperties; //var managedProperties = ManagedPropertyRepository.Instance // .GetTypePropertiesContainer(em.EntityType) // .GetNonReadOnlyCompiledProperties(); foreach (var property in metaProperties) { var columnMeta = property.ColumnMeta; if (columnMeta == null) { continue; } var mp = property.ManagedProperty; if (mp == null) { throw new ArgumentNullException(string.Format("{0}.{1} 属性需要使用托管属性进行编写。", em.Name, mp.Name)); } //列名 var propertyName = property.Name; var columnName = columnMeta.ColumnName; if (string.IsNullOrWhiteSpace(columnName)) { columnName = propertyName; } //类型 var propertyType = property.PropertyType; bool isNullableRef = false; #region 引用关系 if (columnMeta.HasFKConstraint) { var refProperty = mp as IRefProperty; if (refProperty != null) { isNullableRef = refProperty.Nullable; var refMeta = em.Property(refProperty.RefEntityProperty); if (refMeta.ReferenceInfo == null) { throw new InvalidOperationException("refMeta.ReferenceInfo == null"); } //引用实体的类型。 var refTypeMeta = refMeta.ReferenceInfo.RefTypeMeta; if (refTypeMeta != null) { var refTableMeta = refTypeMeta.TableMeta; if (refTableMeta != null) { //如果主键表已经被忽略,那么到这个表上的外键也不能建立了。 //这是因为被忽略的表的结构是未知的,不一定是以这个字段为主键。 if (!this.Database.IsIgnored(refTableMeta.TableName)) { var id = refTypeMeta.Property(Entity.IdProperty); //有时一些表的 Id 只是自增长,但并不是主键,不能创建外键。 if (id.ColumnMeta.IsPrimaryKey) { this._foreigns.Add(new ForeignConstraintInfo() { FkTableName = tableMeta.TableName, PkTableName = refTableMeta.TableName, FkColumn = columnName, PkColumn = id.ColumnMeta.ColumnName, NeedDeleteCascade = refProperty.ReferenceType == ReferenceType.Parent }); } } } } } else if (mp == Entity.TreePIdProperty) { var id = em.Property(Entity.IdProperty); //有时一些表的 Id 只是自增长,但并不是主键,不能创建外键。 if (id.ColumnMeta.IsPrimaryKey) { this._foreigns.Add(new ForeignConstraintInfo() { FkTableName = tableMeta.TableName, PkTableName = tableMeta.TableName, FkColumn = columnName, PkColumn = id.ColumnMeta.ColumnName, NeedDeleteCascade = false }); } } } #endregion var dataType = TypeHelper.IgnoreNullable(propertyType); //对于支持多数据类型的 Id、TreePId 属性进行特殊处理。 if (mp == Entity.IdProperty || mp == Entity.TreePIdProperty) { dataType = em.IdType; } var dbType = columnMeta.DataType.GetValueOrDefault(DbTypeHelper.ConvertFromCLRType(dataType)); var column = new Column(columnName, dbType, columnMeta.DataTypeLength, table); if (columnMeta.IsRequired.HasValue) { column.IsRequired = columnMeta.IsRequired.Value; } else { column.IsRequired = !isNullableRef && !propertyType.IsClass && !TypeHelper.IsNullable(propertyType); } //IsPrimaryKey 的设置放在 IsRequired 之后,可以防止在设置可空的同时把列调整为非主键。 column.IsPrimaryKey = columnMeta.IsPrimaryKey; column.IsIdentity = columnMeta.IsIdentity; table.Columns.Add(column); //读取属性的注释。 if (_readComment) { var commentProperty = mp; var refProperty = commentProperty as IRefProperty; if (refProperty != null) { commentProperty = refProperty.RefEntityProperty; } column.Comment = _commentFinder.TryFindComment(commentProperty); } } table.SortColumns(); this.AddTable(table); }
/// <summary> /// 创建新的Sql语句参数类 /// </summary> /// <param name="columnName">字段名</param> /// <param name="parameterName">参数名</param> /// <param name="value">赋值内容</param> /// <returns>Sql语句参数类</returns> public static SqlParameter Create(String columnName, String parameterName, Object value) { return(SqlParameter.Create(columnName, parameterName, DbTypeHelper.InternalGetDbType(value), value)); }
/// <summary> /// 创建新的Sql语句参数类 /// </summary> /// <param name="columnName">字段名</param> /// <param name="value">赋值内容</param> /// <returns>Sql语句参数类</returns> public static SqlParameter Create(String columnName, Object value) { return(SqlParameter.Create(columnName, columnName.Replace("(", "_").Replace(")", ""), DbTypeHelper.InternalGetDbType(value), value)); }