在EF Code First中有一个描述字段的数据注释? [英] In EF Code First is there a data annotation for description field?
问题描述
在 MS-SQL
中设计表时,您可以选择为每个列添加一个描述
到桌子 EF Code First
可以在数据注释
的帮助下执行相同操作?
While designing a table in MS-SQL
you have a choice to add a description
for each column you add to the table. Is it possible in EF Code First
to do same with help of Data Annotations
?
扩展属性
推荐答案
在使用我的soultion之前,请阅读一下:
https://technet.microsoft.com/en-us/library/ms190243(v = sql.105).aspx
Extended Properties:
https://technet.microsoft.com/en-us/library/ms190243(v=sql.105).aspx
属性:
http://www.dotnetperls.com/attribute
我的解决方案将允许您为这样的任何属性进行阴影描述:
My solution will allow you to do a shadow description for any property like that:
[Description("My Column description!")]
public string RegionCity { get; set; }
注意:
- 复制粘贴soultion,一切都应该有效(不要忘记app.config连接字符串)!
- 可以使用sql命令IF NOT EXISTS检查扩展属性是否已经存在。
-
您可以构建您自己的通用逻辑或C#扩展,以便从任何属性读取描述,这应该是简单的添加一个使用字符串的例子。
- Copy paste the soultion and everything should works (donnot forget the app.config connection string)!
- You can use the sql command IF NOT EXISTS to check if the extended property already exist or not.
You can build your own generic logic or C# extension to read the descirption from any property this should be easy a just have added a an example with string.
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)
{
}
}
}
}
这篇关于在EF Code First中有一个描述字段的数据注释?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!