EF Core自定义属性不适用于modeBuilder.Model.GetEntityTypes()上的对象类型

时间:2018-10-31 08:47:10

标签: c# ef-core-2.1

我有一个自定义属性类,定义如下:

[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public class JsonFieldAttribute : Attribute
{
    public JsonFieldAttribute()
    {
    }
}

通过使用反射来获取此属性在任何类上的用法,效果都很好。没什么。

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

    [JsonField]
    public string Primitive { get; set; }

    [JsonField]
    public Address NonPrimitive { get; set; }
}

但是通过在DbContexts的OnModelCreating上使用modeBuilder.Model.GetEntityTypes()仅适用于原始类型。似乎任何类类型都将被忽略。

  protected override void OnModelCreating(ModelBuilder modelBuilder)
  {
        base.OnModelCreating(modelBuilder);

        foreach (var entityTypes in modelBuilder.Model.GetEntityTypes())
        {
            foreach (var property in entityTypes.GetProperties())
            {
                var memberInfo = property.PropertyInfo ?? (MemberInfo)property.FieldInfo;
                if (memberInfo == null)
                {
                    continue;
                }
                var attr = Attribute.GetCustomAttribute(memberInfo, typeof(JsonFieldAttribute));
                // I've tried various combinations here, but all of them failed
                // var attr = memberInfo?.GetCustomAttribute<JsonFieldAttribute>();
                if (attr == null)
                {
                    continue;
                }
                Console.WriteLine($"Custom attribute {property.Name} {attr.GetType().Name}");
            }
        }
  }

输出包含以下内容:

自定义属性Primitive JsonFieldAttribute

我正在使用.NET Core 2.1.403并打包Microsoft.AspNetCore.All v 2.1.5。 知道为什么NonPrimitive无法正常工作吗?

1 个答案:

答案 0 :(得分:1)

这是因为EF Core术语的集合和实体(自有或常规)类型(即导航属性)不是属性,而是导航,并且不包含在GetProperties中方法结果,但可以使用GetNavigations方法进行检索。

由于IPropertyINavigation具有共同的基础IPropertyBase,因此您可以将它们与Concat方法结合使用,并像这样更改循环:

foreach (var property in entityTypes.GetProperties()
    .Concat<IPropertyBase>(entityType.GetNavigations()))
{
    // ...
}