/// <summary> /// Fill the last N-1 items of the array with /// values of object properties. /// The first element is already set. /// </summary> /// <param name="row"> /// Entity object. /// </param> /// <param name="dbValues"> /// Array to fill. /// </param> protected void GenerateDbValues(T row, object[] dbValues, bool containsIdentityColumn) { int index = 1; foreach (string paramname in m_propertyNameList) { if (containsIdentityColumn) { PropertyInfo propertyInfo = m_propertyInfoDictonary[paramname]; TableColumnAttribute colAttr = propertyInfo.GetCustomAttribute <TableColumnAttribute>(false) as TableColumnAttribute; if (colAttr != null && colAttr.IsPrimaryKey && operationType != OperationType.Delete) { continue; // 跳过主键列. } } dbValues[index] = ConvertNoneToDbNull(m_propertyInfoDictonary[paramname].GetValue(row, null)); if ((m_propertyInfoDictonary[paramname].PropertyType.Name.Contains("Int") && Convert.ToInt32(dbValues[index]) < 1) || (m_propertyInfoDictonary[paramname].PropertyType.Name.Contains("Decimal") && Convert.ToDecimal(dbValues[index]) < 1)) // 实型、整形会默认为0 { dbValues[index] = DBNull.Value; } if (!MapperConstants.DoNotFilterTimeEntities.Contains(this.m_type)) { if (m_propertyInfoDictonary[paramname].PropertyType.Name.Equals("DateTime")) { object datetime = dbValues[index]; dbValues[index] = datetime.Equals(DBNull.Value) ? datetime : Convert.ToDateTime(datetime); } } index++; } }
/// <summary> /// 初始化实体类 /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public IDbContext Set <T>() { StringBuilder stringBuilder = new StringBuilder(); Type t = typeof(T); string tableName = t.Name; TableAttribute tableAttribute = null; if (!tables.ContainsKey(t)) { tableAttribute = t.GetCustomAttribute <TableAttribute>(); if (tableAttribute != null) { tableName = tableAttribute.Name; } tables.Add(t, tableAttribute); string fieldName = string.Empty; TableColumnAttribute tableColumnAttribute = null; t.GetProperties(BindingFlags.Instance | BindingFlags.Public).ToList().ForEach(x => { tableColumnAttribute = x.GetCustomAttribute <TableColumnAttribute>(); if (!tableFileds.ContainsKey(tableName)) { tableFileds.Add(tableName, new Dictionary <string, PropertyInfo>()); } fieldName = x.Name; if (tableColumnAttribute != null) { fieldName = tableColumnAttribute.Name; } tableFileds[tableName].Add(fieldName, x); }); } else { tableAttribute = tables[t]; } stringBuilder.AppendFormat("if object_id('{0}') is null begin ", tables[t].Name); stringBuilder.AppendFormat("create table {0}(", tables[t].Name); StringBuilder commitBuilder = new StringBuilder(); foreach (var item in tableFileds[tables[t].Name]) { stringBuilder.AppendFormat("{0} {1} {2},", item.Key, GetDbType(item.Value.PropertyType), GetOther(item.Value, tableName, commitBuilder)); } if (stringBuilder.ToString().IndexOf(',') >= 0) { stringBuilder.Remove(stringBuilder.Length - 1, 1); } stringBuilder.Append(")"); if (tableAttribute != null && !string.IsNullOrEmpty(tableAttribute.Comments)) { commitBuilder.AppendFormat("exec sp_addextendedproperty N'MS_Description', N'{0}', N'SCHEMA', N'dbo',N'table', N'{1}';", tableAttribute.Comments, tableAttribute.Name); } stringBuilder.Append(commitBuilder); stringBuilder.Append(" end "); sqlExecute.ExecuteSql(stringBuilder.ToString()); return(this); }
public void Property_IsMarkedWithColumnType <TProperty>(Expression <Func <EntityData, TProperty> > property, TableColumnType expected) { // Arrange PropertyInfo propertyInfo = PropertyAssert.GetPropertyInfo <EntityData, TProperty>(property); // Act TableColumnAttribute attr = propertyInfo.GetCustomAttributes <TableColumnAttribute>().Single(); // Assert Assert.Equal(attr.ColumnType, expected); }
/// <summary> /// 获取数据库其他描述 /// </summary> /// <param name="type"></param> /// <returns></returns> private string GetOther(PropertyInfo property, string tableName, StringBuilder commits) { StringBuilder filedDesc = new StringBuilder(); TableColumnAttribute tableColumnAttribute = property.GetCustomAttribute <TableColumnAttribute>(); if (tableColumnAttribute != null) { switch (tableColumnAttribute.ColumnType) { case TableColumnType.PrimaryKey: filedDesc.Append(" primary key "); break; case TableColumnType.ForeignKey: filedDesc.AppendFormat(" constraint fk_{0}_{1} references {2} ", property.Name, tableColumnAttribute.ForeignKeyDec.Substring(0, tableColumnAttribute.ForeignKeyDec.IndexOf("(")).ToString(CultureInfo.InvariantCulture), tableColumnAttribute.ForeignKeyDec); break; case TableColumnType.None: break; default: break; } if (tableColumnAttribute.IsIdentity) { filedDesc.Append(" identity(1,1) "); } if (!string.IsNullOrEmpty(tableColumnAttribute.DefaultValue)) { filedDesc.AppendFormat(" default({0}) ", tableColumnAttribute.DefaultValue); } if (property.PropertyType.IsGenericType && typeof(Nullable <>) == property.PropertyType) { filedDesc.Append(" null "); } else { filedDesc.Append(" not null "); } if (!string.IsNullOrEmpty(tableColumnAttribute.Comments)) { commits.AppendFormat(" EXECUTE sp_addextendedproperty 'MS_Description', '{0}', 'user', 'dbo', 'table', '{1}', 'column', '{2}';", tableColumnAttribute.Comments, tableName, tableColumnAttribute.Name); } } return(filedDesc.ToString()); }
/// <summary> /// 获取数据库列映射 /// 说明: /// 根据数据库的不同,返回结果的key可能需要增加不同的前缀 /// SqlServer(即MSSQL)为 @ /// MySQL为 ? /// Oracle为 : /// </summary> /// <param name="type"></param> /// <returns> /// 返回结果说明: /// key#实体属性名称 /// value#数据库表字段名称 /// </returns> public static Dictionary <String, String> GetColumnMapping(Type type) { Dictionary <String, String> dict = new Dictionary <String, String>(); if (null != type) { String columnMappingKey = type.Name; if (m_tableColumnMappingDict.ContainsKey(columnMappingKey)) { //如果缓存中已经有了,则从缓存中获取 return(m_tableColumnMappingDict[columnMappingKey]); } PropertyInfo[] propertyInfos = type.GetProperties(BindingFlags.Instance | BindingFlags.Public); if (null != propertyInfos && propertyInfos.Length > 0) { TableIgnoreColumnAttribute ignoreColumnAttribute = null; TableColumnAttribute columnAttribute = null; foreach (PropertyInfo propertyInfo in propertyInfos) { //判断是否需要忽略 ignoreColumnAttribute = propertyInfo.GetCustomAttribute <TableIgnoreColumnAttribute>(); if (null == ignoreColumnAttribute) { String key = propertyInfo.Name; if (dict.ContainsKey(key)) { continue; //如果设置了多个列,则只设置一个,其他的不进行映射 } //判断是否有自主设置映射属性 columnAttribute = propertyInfo.GetCustomAttribute <TableColumnAttribute>(); if (null == columnAttribute) { dict[key] = key; } else { dict[key] = columnAttribute.Name; } } } } m_tableColumnMappingDict[columnMappingKey] = dict; } return(dict); }
/// <summary> /// Create a new instance of a multi-columned <see cref="TableAlertProperty{T}"/> based on the given values. /// </summary> /// <param name="tableRows">The values of the table rows.</param> /// <param name="tablePropertyName">The table property name.</param> /// <param name="tableDisplayName">The table property display name.</param> /// <param name="tableRowType">The type of the table's rows.</param> /// <param name="tableAttribute">The attribute applied to the table property.</param> /// <param name="order">The order to use</param> /// <returns>The newly created <see cref="TableAlertProperty{T}"/> instance.</returns> private static TableAlertProperty <Dictionary <string, string> > CreateMultiColumnTableAlertProperty( IList tableRows, string tablePropertyName, string tableDisplayName, Type tableRowType, TablePropertyAttribute tableAttribute, Order order) { // Create the table columns var rows = new List <Dictionary <string, string> >(tableRows.Count); // Initialize the table rows with new dictionaries for (int i = 0; i < tableRows.Count; i++) { rows.Add(new Dictionary <string, string>()); } // We scan the table by columns to we'll handle a single property at a time foreach (PropertyInfo columnProperty in tableRowType.GetProperties()) { // Handle only table column properties TableColumnAttribute tableColumnAttribute = columnProperty.GetCustomAttribute <TableColumnAttribute>(); if (tableColumnAttribute != null) { for (int i = 0; i < tableRows.Count; i++) { rows[i][columnProperty.Name] = PropertyValueToString( tableRows[i], columnProperty, columnProperty.GetValue(tableRows[i]), tableColumnAttribute.FormatString); } } } return(new TableAlertProperty <Dictionary <string, string> >(tablePropertyName, tableDisplayName, order.Next(), tableAttribute.ShowHeaders, CreateTableColumns(tableRowType), rows)); }
/// <summary> /// Map entities to <see cref="TableViewModel"/> by using the decorated properties of the view model entity implementation by <seealso cref="TableColumnAttribute"/>. /// </summary> /// <typeparam name="T">ViewModel entity implementation.</typeparam> /// <param name="entitiesResult"></param> /// <param name="actions"></param> /// <returns></returns> public static TableViewModel Map <T>(PaginatedList <T> entitiesResult, params TableRowActionViewModel[] actions) { Type dtoType = typeof(T); TableViewModel tableViewModel = new TableViewModel(); var properties = dtoType.GetProperties(); List <TableColumnAttribute> dtoAttributes = new List <TableColumnAttribute>(); foreach (var property in properties) { if (property.HasAttribute <TableColumnAttribute>()) { dtoAttributes.Add((TableColumnAttribute)property.GetCustomAttributes(typeof(TableColumnAttribute), false).FirstOrDefault()); } } List <string> tableHeaders = dtoAttributes.OrderBy(x => x.Order).Select(x => x.Name).Distinct().ToList(); tableHeaders.ForEach(x => { tableViewModel.Header.AddCell(x); }); if (entitiesResult.ItemsCount > 0) { foreach (var entity in entitiesResult.Items) { TableRowViewModel tableRow = new TableRowViewModel(); foreach (var property in properties) { if (property.GetCustomAttributes(typeof(EntityIdentifierAttribute), false).Length > 0) { tableRow.Identifier = property.GetValue(entity)?.ToString(); } if (property.HasAttribute <TableColumnAttribute>()) { TableColumnAttribute propertyAttribute = (TableColumnAttribute)property.GetCustomAttributes(typeof(TableColumnAttribute), false).FirstOrDefault(); ITableElement tableElementInstance = (ITableElement)Activator.CreateInstance(propertyAttribute.UIElementType); tableRow.AddCell( propertyAttribute.Order, property.GetValue(entity), tableElementInstance); } } foreach (var action in actions) { List <string> parsedParameters = new List <string>(); foreach (var parameter in action.RawParameters) { if (parameter.StartsWith("[", StringComparison.OrdinalIgnoreCase) && parameter.EndsWith("]", StringComparison.OrdinalIgnoreCase)) { string propertyName = parameter.Substring(1, parameter.Length - 2); string propertyValue = entity.GetType().GetProperty(propertyName)?.GetValue(entity).ToString(); parsedParameters.Add(propertyValue); } else { parsedParameters.Add(parameter); } } tableRow.AddAction(action, parsedParameters); } tableViewModel.AddRow(tableRow); } } tableViewModel.SetPagination(entitiesResult.CurrentPage, entitiesResult.PagesCount); return(tableViewModel); }
/// <summary> /// Создает таблицы в БД для сохранения/загрузки объектов переданного типа /// </summary> /// <returns></returns> public void CreateTableFor(Type type) { //Определение атрибута сохраняемой таблицы TableAttribute dbTable = (TableAttribute)type.GetCustomAttributes(typeof(TableAttribute), true).FirstOrDefault(); if (!Database.Tables.Contains(dbTable.TableName, dbTable.TableScheme)) { if (!Database.Schemas.Contains(dbTable.TableScheme)) { //Если схемы нет в БД, то производится ее создание Schema newSchema = new Schema(Database, dbTable.TableScheme); newSchema.Owner = "dbo"; //Create the schema on the instance of SQL Server. newSchema.Create(); //Define an ObjectPermissionSet that contains the Update and Select object permissions. ObjectPermissionSet obperset = new ObjectPermissionSet(); obperset.Add(ObjectPermission.Select); obperset.Add(ObjectPermission.Update); obperset.Add(ObjectPermission.Insert); obperset.Add(ObjectPermission.Delete); //Grant the set of permissions on the schema to the guest account. newSchema.Grant(obperset, "sa"); } Table newTable = new Table(Database, dbTable.TableName, dbTable.TableScheme); //определение своиств типа List <PropertyInfo> preProrerty = new List <PropertyInfo>(type.GetProperties()); //определение своиств, имеющих атрибут "сохраняемое" List <PropertyInfo> properties = preProrerty.Where(p => p.GetCustomAttributes(typeof(TableColumnAttribute), false).Length != 0).ToList(); foreach (PropertyInfo t in properties) { TableColumnAttribute tca = (TableColumnAttribute)t.GetCustomAttributes(typeof(TableColumnAttribute), false).FirstOrDefault(); Column newColumn = new Column(newTable, tca.ColumnName); DataType storedType = GetDataType(t, tca); if (storedType != null) { newColumn.DataType = storedType; } else { throw new Exception("для типа " + t.PropertyType.Name + " не удается определить хранимый тип в БД"); } newColumn.Nullable = true; if (tca.ColumnName == dbTable.PrimaryKey) { // Определение своиств ключа newColumn.Nullable = false; newColumn.Identity = true; newColumn.IdentitySeed = 1; newColumn.IdentityIncrement = 1; } newTable.Columns.Add(newColumn); } // Create a PK Index for the table Index index = new Index(newTable, "PK_" + dbTable.TableName) { IndexKeyType = IndexKeyType.DriPrimaryKey }; // The PK index will consist of 1 column, "ID" index.IndexedColumns.Add(new IndexedColumn(index, dbTable.PrimaryKey)); // Add the new index to the table. newTable.Indexes.Add(index); // Physically create the table in the database newTable.Create(); //Database.Tables.Add(newTable); if (newTable.Columns.Contains("IsDeleted")) { // Определение своиств ключа Column col = newTable.Columns["IsDeleted"]; string defName = dbTable.TableName + "_" + col.Name; DefaultConstraint dc = col.AddDefaultConstraint(defName); dc.Text = "((0))"; dc.Create(); col.Nullable = false; col.Alter(); //Default def = new Default(Database, defName, dbTable.TableScheme) //{ // TextHeader = "CREATE DEFAULT " + dbTable.TableScheme + ".[" + defName + "] AS", // TextBody = "((0))" //}; ////Create the default on the instance of SQL Server. //def.Create(); ////Bind the default to a column in a table in AdventureWorks2012 //def.BindToColumn(dbTable.TableName, col.Name, dbTable.TableScheme); } } else { //Получение таблицы Table table = Database.Tables[dbTable.TableName, dbTable.TableScheme]; //определение своиств типа List <PropertyInfo> preProrerty = new List <PropertyInfo>(type.GetProperties()); //определение своиств, имеющих атрибут "сохраняемое" List <PropertyInfo> properties = preProrerty.Where(p => p.GetCustomAttributes(typeof(TableColumnAttribute), false).Length != 0).ToList(); //Проверка таблицы на наличие соответствующх колонок, их имен и типа хранимого значения foreach (PropertyInfo p in properties) { TableColumnAttribute tca = (TableColumnAttribute)p.GetCustomAttributes(typeof(TableColumnAttribute), false).FirstOrDefault(); //Для начала определяется, можно ли сохранить тип в БД DataType storedType = GetDataType(p, tca); if (storedType == null) { throw new Exception("для типа " + p.PropertyType.Name + " не удается определить хранимый тип в БД"); } //Проверка наличия колонки с заданным именем в таблице if (!table.Columns.Contains(tca.ColumnName)) { //Если колонки с заданным именем нет в таблице //то производится ее создание Column newColumn = new Column(table, tca.ColumnName); newColumn.DataType = storedType; newColumn.Nullable = true; if (tca.ColumnName == dbTable.PrimaryKey) { // Определение своиств ключа newColumn.Nullable = false; newColumn.Identity = true; newColumn.IdentitySeed = 1; newColumn.IdentityIncrement = 1; newColumn.Create(); //table.Columns.Add(newColumn); // Create a PK Index for the table Index index = new Index(table, "PK_" + dbTable.TableName) { IndexKeyType = IndexKeyType.DriPrimaryKey }; // The PK index will consist of 1 column, "ID" index.IndexedColumns.Add(new IndexedColumn(index, dbTable.PrimaryKey)); // Add the new index to the table. table.Indexes.Add(index); continue; } newColumn.Create(); continue; } //Проверка типа хранимого значения колонки Column col = table.Columns[tca.ColumnName]; if (col.DataType.Name != storedType.Name) { //Если тип колонки в таблице не соответствует типу для хранения //то производится смена типа col.DataType = storedType; col.Alter(); continue; } if (col.DataType.MaximumLength != storedType.MaximumLength && storedType.MaximumLength != 0) { //Если размер типа данных колонки в таблице не соответствует размеру для хранения //то производится изменение размера col.DataType.MaximumLength = storedType.MaximumLength; col.Alter(); continue; } } } }
/// <summary> /// Проверяет наличие и корректность таблицы в БД для сохранения/загрузки объектов переданного типа /// </summary> /// <returns></returns> public void CheckTableFor(Type type) { //Определение атрибута сохраняемой таблицы TableAttribute dbTable = (TableAttribute)type.GetCustomAttributes(typeof(TableAttribute), true).FirstOrDefault(); if (!Database.Tables.Contains(dbTable.TableName, dbTable.TableScheme)) { //Если отстствует таблица, предназначенная для сохранения объектов //переданного типа то кидается исключение throw new DbTableAttributeException(type, dbTable); } //Получение таблицы Table table = Database.Tables[dbTable.TableName, dbTable.TableScheme]; //определение своиств типа List <PropertyInfo> preProrerty = new List <PropertyInfo>(type.GetProperties()); //определение своиств, имеющих атрибут "сохраняемое" List <PropertyInfo> properties = preProrerty.Where(p => p.GetCustomAttributes(typeof(TableColumnAttribute), false).Length != 0).ToList(); //Проверка таблицы на наличие соответствующх колонок, их имен и типа хранимого значения //List<ColumnError> errors = new List<ColumnError>(); string checkResult = ""; foreach (PropertyInfo p in properties) { TableColumnAttribute tca = (TableColumnAttribute)p.GetCustomAttributes(typeof(TableColumnAttribute), false).FirstOrDefault(); //Для начала определяется, можно ли сохранить тип в БД DataType storedType = GetDataType(p, tca); if (storedType == null) { throw new Exception("для типа " + p.PropertyType.Name + " не удается определить хранимый тип в БД"); } //Проверка наличия колонки с заданным именем в таблице if (!table.Columns.Contains(tca.ColumnName)) { //Если колонки с заданным именем нет в таблице //то инф-я об этом добавлется в результат проверки //errors.Add(new ColumnError(tca.ColumnName, ColumnErrorType.NoFind)); if (checkResult != "") { checkResult += ",\n"; } checkResult += "Колонка с именем " + tca.ColumnName + " отсутствует в таблице"; continue; } //Проверка типа хранимого значения колонки Column col = table.Columns[tca.ColumnName]; if (col.DataType.Name != storedType.Name) { //Если тип колонки в таблице не соответствует типу для хранения //то инф-я об этом добавлется в результат проверки //errors.Add(new ColumnError(tca.ColumnName, ColumnErrorType.InvalidType)); if (checkResult != "") { checkResult += ",\n"; } checkResult += "Тип колонки " + tca.ColumnName + " не соответствует типу хранения для " + p.Name + "(" + p.PropertyType.Name + ")"; continue; } if (col.DataType.MaximumLength != storedType.MaximumLength && storedType.MaximumLength != 0) { //Если размер типа данных колонки в таблице не соответствует размеру для хранения //то инф-я об этом добавлется в результат проверки //errors.Add(new ColumnError(tca.ColumnName, ColumnErrorType.InvalidSize)); if (checkResult != "") { checkResult += ",\n"; } checkResult += "Размер колонки " + tca.ColumnName + "(" + col.DataType.MaximumLength + ")" + " не соответствует размеру хранения для " + p.Name + "(" + storedType.MaximumLength + ")"; continue; } //if (tca.ColumnName.ToLower() == "isdeleted") //{ // // Определение своиств ключа // DefaultConstraint dc = col.DefaultConstraint; // //newColumn.AddDefaultConstraint( =) "((0))"); //} } //if(errors.Count > 0) throw new DbTableColumnsAttributeException(type,errors.ToArray()); if (checkResult != "") { throw new DbTableColumnsAttributeException(type, checkResult); } }
/* * Управление транзакциями */ /* * База данных CAS */ #region private DataType GetDataType(PropertyInfo propertyInfo, TableColumnAttribute attr) /// <summary> /// Определяет какой тип значения нужен для сохранения переданного своиства в БД /// </summary> /// <param name="propertyInfo"></param> /// <param name="attr"></param> /// <returns></returns> private DataType GetDataType(PropertyInfo propertyInfo, TableColumnAttribute attr) { //Проверка на то, является ли тип своиства потомком BaseSmartCoreObject if (propertyInfo.PropertyType.IsSubclassOf(typeof(BaseEntityObject))) { return(DataType.Int); } if (propertyInfo.PropertyType.GetInterface(typeof(IBaseEntityObject).Name) != null) { return(DataType.Int); } if (propertyInfo.PropertyType.IsEnum) { return(DataType.SmallInt); } string typeName = propertyInfo.PropertyType.Name.ToLower(); switch (typeName) { case "byte[]": return(DataType.VarBinary(-1)); case "string": return(DataType.NVarChar(attr != null && (attr.Size < 0 || attr.Size > 256) ? attr.Size : 256)); case "int32": return(DataType.Int); case "int16": return(DataType.SmallInt); case "datetime": return(DataType.DateTime); case "bool": case "boolean": return(DataType.Bit); case "double": return(DataType.Float); case "detectionphase": case "flightregime": case "kitcostcondition": case "powerloss": case "runupcondition": case "runuptype": case "shutdowntype": case "thrustlever": case "weathercondition": return(DataType.SmallInt); case "highlight": case "timespan": case "workpackagestatus": return(DataType.Int); case "directivethreshold": return(DataType.VarBinary(DirectiveThreshold.SerializedDataLength)); case "componentdirectivethreshold": return(DataType.VarBinary(ComponentDirectiveThreshold.SerializedDataLength)); case "maintenancedirectivethreshold": return(DataType.VarBinary(MaintenanceDirectiveThreshold.SerializedDataLength)); case "trainingthreshold": return(DataType.VarBinary(TrainingThreshold.SerializedDataLength)); case "lifelength": return(DataType.VarBinary(Lifelength.SerializedDataLength)); default: return(null); } }