我有这样的DefaultAttribute
定义:
[AttributeUsage(AttributeTargets.Property)] public class DefaultAttribute : Attribute { ////// Specifies this property has a default value upon creation. /// /// The default value of the property. /// Set to true if the value is not quoted in the DDL. public DefaultAttribute(object defaultValue, bool useAsLiteral = false) { DefaultValue = defaultValue; UseAsLiteral = useAsLiteral; } public object DefaultValue { get; private set; } ////// True if the default value is not quoted in the DDL /// public bool UseAsLiteral { get; private set; } }
我用这个属性装饰了我的几个实体,如下所示:
public class MyEntity { . . . (other properties) . . . [StringLength(200)] [Required] [Default("My Default Description!")] public string Description { get; set; } }
然后,在我的数据库上下文中的OnModelCreating方法中,我编写了以下代码:
//examine custom annotations for shaping the schema in the database. foreach (var entityType in builder.Model.GetEntityTypes()) foreach (var property in entityType.GetProperties()) { var annotations = property.GetAnnotations(); // evaluate default values var defaultAnnotation = annotations.FirstOrDefault(x => x.Name == typeof(DefaultAttribute).FullName); if (defaultAnnotation != null) { var defaultValue = defaultAnnotation.Value as DefaultAttribute; if (defaultValue == null) continue; if (defaultValue.UseAsLiteral) property.Npgsql().DefaultValueSql = defaultValue.DefaultValue.ToString(); else property.Npgsql().DefaultValue = defaultValue.DefaultValue; } }
在添加迁移(以及后续数据库更新)时,我的期望是默认值为"我的默认描述!".对于...的Description
列,MyEntity
但事实并非如此.
我没有得到任何错误,但它没有像我怀疑的那样做,并且踩到OnModelCreating
断点也难以置信.
我这样做了吗?它不起作用吗?它只是不支持EF7吗?或者我的PostgreSQL实现不支持它?任何见解将不胜感激.
更新 使用@ IvanStoev的答案,我能够使用一些小的修改(.NET Core中的反射与传统的有点不同):
//examine custom annotations for shaping the schema in the database. foreach (var entityType in builder.Model.GetEntityTypes()) foreach (var property in entityType.GetProperties()) { var memberInfo = property.PropertyInfo ?? (MemberInfo)property.FieldInfo; var defaultValue = memberInfo?.GetCustomAttribute(); if (defaultValue == null) continue; if (defaultValue.UseAsLiteral) property.Npgsql().DefaultValueSql = defaultValue.DefaultValue.ToString(); else property.Npgsql().DefaultValue = defaultValue.DefaultValue; }
这就像一个冠军.
EF Core对您的自定义属性一无所知,因此无法将其作为注释进行发现和公开(通常这是一个不同的东西,不一定与属性相关联).
您必须从存在PropertyInfo
或从FieldInfo
存在时手动提取属性:
foreach (var entityType in builder.Model.GetEntityTypes()) foreach (var property in entityType.GetProperties()) { var memberInfo = property.PropertyInfo ?? (MemberInfo)property.FieldInfo; if (memberInfo == null) continue; var defaultValue = Attribute.GetCustomAttribute(memberInfo, typeof(DefaultAttribute)) as DefaultAttribute; if (defaultValue == null) continue; if (defaultValue.UseAsLiteral) property.Npgsql().DefaultValueSql = defaultValue.DefaultValue.ToString(); else property.Npgsql().DefaultValue = defaultValue.DefaultValue; }