C# 为DbContext中的每个DbSet准备字段和显示名列表

C# 为DbContext中的每个DbSet准备字段和显示名列表,c#,asp.net-mvc-5,entity-framework-6,.net-4.0,ef-database-first,C#,Asp.net Mvc 5,Entity Framework 6,.net 4.0,Ef Database First,在我的项目(MVC5、EF6、Net4.8)中,我需要准备一个包含所有字段名及其显示名列表的文档。 例如,我的DbContext中有以下类: public class Teacher { [Key] public int Id { get; set; } [Display(Name = "First name of the teacher")] public string FirstName { get; set; } [Display(Name = "L

在我的项目(MVC5、EF6、Net4.8)中,我需要准备一个包含所有字段名及其显示名列表的文档。 例如,我的DbContext中有以下类:

public class Teacher
{
    [Key]
    public int Id { get; set; }
    [Display(Name = "First name of the teacher")]
    public string FirstName { get; set; }
    [Display(Name = "Last name of the teacher")]
    public string LastName { get; set; }
    [Display(Name = "Phone number of the teacher")]
    public string Phone { get; set; }
}

public class Student
{
    [Key]
    public int Id { get; set; }
    [Display(Name = "First name of the student")]
    public string FirstName { get; set; }
    [Display(Name = "Last name of the student")]
    public string LastName { get; set; }
    [Display(Name = "Birthdate of the student")]
    public DateTime Birthdate { get; set; }
}
我需要每个字段名及其对应显示名的列表,如下所示:

["Teacher", "Id", null]
["Teacher", "FirstName", "First name of the teacher"]
["Teacher", "LastName", "Last name of the teacher"]
["Teacher", "Phone", "Phone number of the teacher"]

["Student", "Id", null]
["Student", "FirstName", "First name of the student"]
["Student", "LastName", "Last name of the student"]
["Student", "Birthdate", "Birthdate of the student"]

是否可以自动创建这样的列表?

您可以使用反射:

typeof(YourContext)
    .GetProperties()
    .Where(prop => prop.PropertyType.IsGenericType
        && prop.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
    .SelectMany(dbSet => dbSet.PropertyType.GetGenericArguments()
        .Single()
        .GetProperties()
        .Select(prop => new [] { prop.DeclaringType.Name, prop.Name, prop.GetCustomAttribute<DisplayAttribute>()?.Name }))
    .ToList();
typeof(YourContext)
.GetProperties()
.Where(prop=>prop.PropertyType.IsGenericType
&&prop.PropertyType.GetGenericTypeDefinition()==typeof(DbSet))
.SelectMany(dbSet=>dbSet.PropertyType.GetGenericArguments()
.Single()
.GetProperties()
.Select(prop=>new[]{prop.DeclaringType.Name、prop.Name、prop.GetCustomAttribute()?.Name}))
.ToList();

首先迭代
YourContext
的所有属性,过滤掉
DbSet
类型的属性,然后迭代每个
DbSet
的泛型类型的属性,并选择一个按您请求的格式展开的数组列表。

您可以使用反射:

typeof(YourContext)
    .GetProperties()
    .Where(prop => prop.PropertyType.IsGenericType
        && prop.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
    .SelectMany(dbSet => dbSet.PropertyType.GetGenericArguments()
        .Single()
        .GetProperties()
        .Select(prop => new [] { prop.DeclaringType.Name, prop.Name, prop.GetCustomAttribute<DisplayAttribute>()?.Name }))
    .ToList();
typeof(YourContext)
.GetProperties()
.Where(prop=>prop.PropertyType.IsGenericType
&&prop.PropertyType.GetGenericTypeDefinition()==typeof(DbSet))
.SelectMany(dbSet=>dbSet.PropertyType.GetGenericArguments()
.Single()
.GetProperties()
.Select(prop=>new[]{prop.DeclaringType.Name、prop.Name、prop.GetCustomAttribute()?.Name}))
.ToList();

首先迭代
YourContext
的所有属性,过滤掉
DbSet
类型的属性,然后迭代每个
DbSet
的泛型类型属性,并选择一个按您要求的格式展开的数组列表。

谢谢,但它会引发以下错误:PropertyInfo不包含“GetGenericArguments”的定义,并且找不到接受“PropertyInfo”类型的第一个参数的可访问扩展方法“GetGenericArguments”(是否缺少using指令或程序集引用?)解释代码总是一个好主意,而不是放弃它,希望它不被理解。另外,您是否打算使用
dbSet.PropertyType.GetGenericArguments()
?谢谢,但它会引发以下错误:PropertyInfo不包含“GetGenericArguments”的定义,并且找不到接受“PropertyInfo”类型的第一个参数的可访问扩展方法“GetGenericArguments”(是否缺少using指令或程序集引用?)解释代码总是一个好主意,而不是放弃它,希望它不被理解。另外,您是否打算使用
dbSet.PropertyType.GetGenericArguments()