当前位置:  开发笔记 > 编程语言 > 正文

在EF7(核心)OnModelCreating中使用自定义属性

如何解决《在EF7(核心)OnModelCreating中使用自定义属性》经验,为你挑选了1个好方法。

我有这样的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;
    }

这就像一个冠军.



1> Ivan Stoev..:

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;
    }

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有