在EF7(核心)OnModelCreating中使用自定义属性 [英] Using a custom attribute in EF7 (core) OnModelCreating
问题描述
我有一个 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 $ c $中提取属性c>如果存在:
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中使用自定义属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!