我有一个 DefaultAttribute 定义,如下所示:
I have a DefaultAttribute defined like so:
[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; } }我已经用此属性装饰了几个实体,如下所示:
I have decorated several of my entities with this attribute, like so:
public class MyEntity { . . . (other properties) . . . [StringLength(200)] [Required] [Default("My Default Description!")] public string Description { get; set; } }然后,在数据库上下文的OnModelCreating方法中,编写了以下内容代码:
Then, in my OnModelCreating method in my database context, I wrote the following code:
//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; } }我期望添加迁移时,(以及后续数据库更新)是默认值为我的默认描述!。对于 MyEntity 的说明列...,但是不是这种情况。
My expectation, when adding a migration, (and subsequent database update) is that there would be a default value of "My Default Description!" for the Description column of MyEntity... however, that is not the case.
我没有收到任何错误,但是没有按照我所怀疑的那样工作,并且很难进入具有断点的 OnModelCreating
I'm not getting any errors, but it's not doing as I would suspect, and stepping into OnModelCreating with a breakpoint is also inexplicably difficult to do.
我这样做正确吗?就是行不通吗? EF7不支持吗?还是我的PostgreSQL实现不支持它?任何见识将不胜感激。
Am I doing this correctly? Does it just not work? Is it just not supported in EF7? Or is it not supported in my PostgreSQL implementation? Any insight would be appreciated.
更新 使用@IvanStoev的答案,我能够将此进行一些较小的修改(.NET Core中的反映与传统有所不同):
UPDATE Using @IvanStoev's answer, I was able to get this to work with some minor modifiactions (Reflection in .NET Core a bit different from traditional):
//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<DefaultAttribute>(); if (defaultValue == null) continue; if (defaultValue.UseAsLiteral) property.Npgsql().DefaultValueSql = defaultValue.DefaultValue.ToString(); else property.Npgsql().DefaultValue = defaultValue.DefaultValue; }这很像冠军。
推荐答案EF Core对您的自定义属性一无所知,因此无法发现它并将其作为注释公开(通常这是另一回事,不一定与之关联)属性)。
EF Core knows nothing about your custom attribute, so there is no way it to be discovered and exposed as annotation (which in general is a different thing and not necessarily associated with attribute).
您必须手动从 PropertyInfo 或 FieldInfo 如果存在:
You have to extract the attribute manually from PropertyInfo or FieldInfo when present:
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; }更多推荐
在EF7(核心)OnModelCreating中使用自定义属性
发布评论