在EF Code First中是否有描述字段的数据注释?

时间:2016-08-17 12:34:19

标签: sql-server entity-framework ef-code-first data-annotations

MS-SQL中设计表时,您可以选择为添加到表中的每列添加description。在EF Code First的帮助下,Data Annotations是否可以这样做?

1 个答案:

答案 0 :(得分:0)

在你使用我的灵魂之前,请阅读一下:

扩展属性:
https://technet.microsoft.com/en-us/library/ms190243(v=sql.105).aspx

<强>属性:
http://www.dotnetperls.com/attribute

我的解决方案允许您为任何属性执行阴影描述:

[Description("My Column description!")]
public string RegionCity { get; set; }

备注:

  • 复制粘贴灵魂,一切都应该工作(不要忘记app.config连接字符串)!
  • 您可以使用sql命令IF NOT EXISTS来检查扩展属性是否已存在。
  • 您可以构建自己的通用逻辑或C#扩展来从任何属性中读取描述,这应该很简单,只需添加一个带字符串的示例。

    using System;
    using System.Linq;
    
    namespace EntityFrameworkDemo
    {
     using System.Data.Entity;
    
    public class Program
    {
        public static void Main()
        {
            Database.SetInitializer(new DropCreateDatabaseAlways<MyDbContext>());
    
    
            using (var myDbContext = new MyDbContext("DefaultConnection"))
            {
                // Maybe you do not need this line!
                myDbContext.Database.Initialize(true);
    
                // Adding one time or use the IF NOT EXISTS SQL Command!
                var c = new ColumnsDescription();
                c.AddColumnsDescriptions(myDbContext);
    
                var region = new Region { RegionCity = "Test 1", RegionSeconcdCity = "Test2" };
                myDbContext.Regions.Add(region);
                myDbContext.SaveChanges();
            }
    
    
            // Reading the extended properties
            using (var myDbContext = new MyDbContext("DefaultConnection"))
            {
                var ep = "select value from fn_listextendedproperty('MS_Description','schema','dbo','table', 'Regions', 'column', 'RegionCity');";
    
                // For example you can read your extend property like following or you make a generic reader
                var properties = myDbContext.Database.SqlQuery<string>(ep).First();
    
                Console.WriteLine(properties);
            }
        }
    
        [AttributeUsage(AttributeTargets.Property)]
        public class DescriptionAttribute : Attribute
        {
            string value;
    
            public DescriptionAttribute(string id)
            {
                this.value = id;
            }
    
            public string Value
            {
                get { return this.value; }
            }
        }
    
        public class ColumnsDescription
        {
            public void AddColumnsDescriptions(DbContext mydbContext)
            {
                // Fetch all the DbContext class public properties which contains your attributes
                var dbContextProperies = typeof(DbContext).GetProperties().Select(pi => pi.Name).ToList();
    
                // Loop each DbSets of type T
                foreach (var item in typeof(MyDbContext).GetProperties()
                    .Where(p => dbContextProperies.IndexOf(p.Name) < 0)
                    .Select(p => p))
                {
                    if (!item.PropertyType.GetGenericArguments().Any())
                    {
                        continue;
                    }
    
                    // Fetch the type of "T"
                    var entityModelType = item.PropertyType.GetGenericArguments()[0];
                    var descriptionInfos = from prop in entityModelType.GetProperties()
                                           where prop.GetCustomAttributes(typeof(DescriptionAttribute), true).Any()
                                           select new { ColumnName = prop.Name, Attributes = prop.CustomAttributes };
    
                    foreach (var descriptionInfo in descriptionInfos)
                    {
                        // Sql to create the description column and adding 
                        var addDiscriptionColumnSql =
                            @"sp_addextendedproperty  @name = N'MS_Description', @value = '"
                            + descriptionInfo.Attributes.First().ConstructorArguments.First()
                            + @"', @level0type = N'Schema', @level0name = dbo,  @level1type = N'Table',  @level1name = "
                            + entityModelType.Name + "s" + ", @level2type = N'Column', @level2name ="
                            + descriptionInfo.ColumnName;
    
                        var sqlCommandResult = mydbContext.Database.ExecuteSqlCommand(addDiscriptionColumnSql);
                    }
                }
            }
        }
    
        public class Region
        {
            public int Id { get; set; }
    
            [Description("My Column description!")]
            public string RegionCity { get; set; }
    
            [Description("My Second Column description!")]
            public string RegionSeconcdCity { get; set; }
    
        }
    
        public class MyDbContext : DbContext
        {
            public DbSet<Region> Regions { get; set; }
    
            public MyDbContext(string connectionString)
                : base("name=" + connectionString)
            {
            }
        }
    }
    }