Search code examples
c#asp.net-mvc-5entity-framework-6.net-4.0ef-database-first

Prepare a List of fields and displaynames for each DbSet in DbContext


In my project (MVC5, EF6, .Net4.8), I need to prepare a document that contains the list of all field names and their DisplayNames. For example, I have the following Classes in my 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; }
}

And I need a list of each field name and its corresponding DisplayName like below:

["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"]

Is it possible to create such a list automatically?


Solution

  • You could use reflection:

    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();
    

    This first iterates over all the properties of YourContext, filters out those that are of type DbSet<>, then iterates over the properties of the generic type of each DbSet<> and selects a flattened list of arrays, in the format you requested.