using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using System.Data.Common; using System.Data.Entity; using System.Data.SqlClient; using System.Text.RegularExpressions; namespace ChangkeTec.Utils { public class DbDescriptionUpdater where TContext : System.Data.Entity.DbContext { public DbDescriptionUpdater(TContext context) { this.context = context; } Type contextType; TContext context; DbTransaction transaction; public void UpdateDatabaseDescriptions() { contextType = typeof(TContext); this.context = context; var props = contextType.GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); transaction = null; try { context.Database.Connection.Open(); transaction = context.Database.Connection.BeginTransaction(); foreach (var prop in props) { if (!prop.PropertyType.InheritsOrImplements((typeof(DbSet<>)))) continue; if(!prop.CanWrite)continue; var tableType = prop.PropertyType.GetGenericArguments()[0]; SetTableDescriptions(tableType); } transaction.Commit(); } catch { transaction?.Rollback(); throw; } finally { if (context.Database.Connection.State == System.Data.ConnectionState.Open) context.Database.Connection.Close(); } } private void SetTableDescriptions(Type tableType) { string fullTableName = context.GetTableName(tableType); Regex regex = new Regex(@"(\[\w+\]\.)?\[(?.*)\]"); Match match = regex.Match(fullTableName); string tableName; if (match.Success) tableName = match.Groups["table"].Value; else tableName = fullTableName; var tableAttrs = tableType.GetCustomAttributes(typeof(TableAttribute), false); if (tableAttrs.Length > 0) tableName = ((TableAttribute)tableAttrs[0]).Name; var table_attrs = tableType.GetCustomAttributes(typeof(DescriptionAttribute), false); if (table_attrs != null && table_attrs.Length > 0) SetTableDescription(tableName, ((DescriptionAttribute)table_attrs[0]).Description); foreach (var prop in tableType.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)) { if (prop.PropertyType.IsClass && prop.PropertyType != typeof(string))continue; var attrs = prop.GetCustomAttributes(typeof(NotMappedAttribute), false); if (attrs.Length > 0) continue; attrs = prop.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attrs != null && attrs.Length > 0) SetColumnDescription(tableName, prop.Name, ((DescriptionAttribute)attrs[0]).Description); } } private void SetColumnDescription(string tableName, string columnName, string description) { string strGetDesc = "select [value] from fn_listextendedproperty('MS_Description','schema','dbo','table',N'" + tableName + "','column',null) where objname = N'" + columnName + "';"; var prevDesc = RunSqlScalar(strGetDesc); if (prevDesc == null) { RunSql(@"EXEC sp_addextendedproperty @name = N'MS_Description', @value = @desc, @level0type = N'Schema', @level0name = 'dbo', @level1type = N'Table', @level1name = @table, @level2type = N'Column', @level2name = @column;", new SqlParameter("@table", tableName), new SqlParameter("@column", columnName), new SqlParameter("@desc", description)); } else { RunSql(@"EXEC sp_updateextendedproperty @name = N'MS_Description', @value = @desc, @level0type = N'Schema', @level0name = 'dbo', @level1type = N'Table', @level1name = @table, @level2type = N'Column', @level2name = @column;", new SqlParameter("@table", tableName), new SqlParameter("@column", columnName), new SqlParameter("@desc", description)); } } private void SetTableDescription(string tableName, string description) { string strGetDesc = "select [value] from fn_listextendedproperty('MS_Description','schema','dbo','table',N'" + tableName + "',null,null);"; var prevDesc = RunSqlScalar(strGetDesc); if (prevDesc == null) { RunSql(@"EXEC sp_addextendedproperty @name = N'MS_Description', @value = @desc, @level0type = N'Schema', @level0name = 'dbo', @level1type = N'Table', @level1name = @table;", new SqlParameter("@table", tableName), new SqlParameter("@desc", description)); } else { RunSql(@"EXEC sp_updateextendedproperty @name = N'MS_Description', @value = @desc, @level0type = N'Schema', @level0name = 'dbo', @level1type = N'Table', @level1name = @table;", new SqlParameter("@table", tableName), new SqlParameter("@desc", description)); } } DbCommand CreateCommand(string cmdText, params SqlParameter[] parameters) { var cmd = context.Database.Connection.CreateCommand(); cmd.CommandText = cmdText; cmd.Transaction = transaction; foreach (var p in parameters) cmd.Parameters.Add(p); return cmd; } void RunSql(string cmdText, params SqlParameter[] parameters) { var cmd = CreateCommand(cmdText, parameters); cmd.ExecuteNonQuery(); } object RunSqlScalar(string cmdText, params SqlParameter[] parameters) { var cmd = CreateCommand(cmdText, parameters); return cmd.ExecuteScalar(); } } }