EF Code First下支持在SQL Server中的表/字段的说明

Ado.EF目前不支持添加在SQL Server中的说明,在类或属性里添加说明/备注/Attribute,生成数据库时,表或字段里不会有相应的说明/备注,但在实际的开发中是很有必要的。数据库生成后,一般由DBA接手,但DBA可能并不了解每个字段的意义。在此,在本文中给出支持此功能的实现方法。 

 

源码下载:这里

 

原理

  1. 首先我们建立一个自定义Attribute类DBDescriptionAttribute,它包含一个属性Description来保存设置在数据库的说明文字
  2. 从DbContext中取得每个类对应的表名和列名
  3. 调用SQL Server的函数fn_listextendedproperty查表或字段是否存在“说明”属性,SQL Server中的说明属性对应的是“MS_Description"
select [value] from fn_listextendedproperty('MS_Description','schema','dbo','table',N'Students','column',null)
select [value] from fn_listextendedproperty('MS_Description','schema','dbo','table',N'Students','column',null) where objname = N'Age'

     4. 调用SQL Server存储过程sp_addextendedproperty/sp_updateextendedproperty来添加或修改表/列的“说明”属性

EXEC sp_addextendedproperty  N'MS_Description',  N'学生表',  N'Schema',  N'dbo',  N'Table',   N'Students' 
EXEC sp_updateextendedproperty N'MS_Description', N'年纪', N'Schema', N'dbo', N'Table',  N'Students', N'Column', N'Age'

 

得到Table名

找到DbContext中包含的表,在DbContext中包含的所有实现DbSet<T>的属性,得到相应的类型TableType,利用ObjectContext.CreateObjectSet<T>().ToTraceString()取相应执行的Sql语句,它是EF自动生成的,当它在创建Set时,会生成一个包含所有字段和表名的Sql语句,如:SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[Age] AS [Age] FROM [dbo].[Students] AS [Extent1] ,正则解析此句得到表名。

得到Column名

拿到表对应的类型后,轮循所有公共属性,检查是否有指定属性DBDescriptionAttribute,如果有,再检查是否有ColumnAttribute属性设置的Name值,如果不为空,则取出备用,如果为空,默认列名即为Property.Name。

 

 两个方法过程如图所示:

 

 

具体实现请看源码。

执行点为Migrations\Configuration中的Seed方法(此方法在执行完迁移后调用)

internal sealed class Configuration : DbMigrationsConfiguration<Models.EFTestContext>
{

        public Configuration()
        {
            AutomaticMigrationsEnabled = true;
        } 

        protected override void Seed(Models.EFTestContext context)
        {
            var updater = new DBDescriptionUpdater<EFTestContext>(context);
            updater.UpdateDatabaseDescriptions();
        }
}

 

实现后在程序包管理控制台中执行:update-database –verbos –force,再到SSMS中检查表/字段是否添加/修改成功。

 

另一解决方案:

直接把类或属性的注释取出来,作为在数据库中的说明文字,可以在App_Data下添加一个嵌入的XML文件来保存这些注释,将以上方法中的用反射来取说明文字改成从XML文件中取说明文字即可。

 

posted @ 2015-09-10 16:10  Tang.Lang  阅读(3798)  评论(1编辑  收藏  举报