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

EF Core custom attributes not working for object types on modeBuilder.Model.GetEntityTypes()

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

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

通过使用反射获取此属性,在任何 class 上使用都非常完美。没什么好看的。

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() 仅适用于原始类型。似乎任何 class 类型都被忽略了。

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

输出包含以下内容:

自定义属性基元 JsonFieldAttribute

我正在使用 .NET Core 2.1.403 和软件包 Microsoft.AspNetCore.All v 2.1.5。 知道为什么 NonPrimitive 不起作用吗?

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

由于 IPropertyINavigation 共享一个公共基础 IPropertyBase,您可以将它们与 Concat 方法组合并像这样更改循环:

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