我的DefaultAttribute
定义如下:
[AttributeUsage(AttributeTargets.Property)]
public class DefaultAttribute : Attribute
{
/// <summary>
/// Specifies this property has a default value upon creation.
/// </summary>
/// <param name="defaultValue">The default value of the property.</param>
/// <param name="useAsLiteral">Set to true if the value is <em>not</em> quoted in the DDL.</param>
public DefaultAttribute(object defaultValue, bool useAsLiteral = false)
{
DefaultValue = defaultValue;
UseAsLiteral = useAsLiteral;
}
public object DefaultValue { get; private set; }
/// <summary>
/// True if the default value is not quoted in the DDL
/// </summary>
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;
}
}
我的期望是,在添加迁移(以及后续数据库更新)时,会有一个默认值为&#34;我的默认描述!&#34;对于Description
的{{1}}列...但是,情况并非如此。
我没有收到任何错误,但它并没有像我怀疑的那样做,而且使用断点进入MyEntity
也难以置信。
我这样做是否正确?它不起作用吗?它只是不支持EF7吗?或者我的PostgreSQL实现不支持它?任何见解都将不胜感激。
更新 使用@ IvanStoev的答案,我能够使用一些小的修改(.NET Core中的反射与传统的有点不同):
OnModelCreating
这就像一个冠军。
答案 0 :(得分:11)
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;
}