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

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

Question

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?

1
0
3/12/2020 1:24:30 PM

Accepted Answer

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.

2
3/12/2020 2:29:20 PM

Popular Answer

You can use Reflection to get the expected result :

private static List<List<string>> GetMembers(Type type)
{
    return type.GetProperties()
    .Select(x => new List<string> 
    { 
        type.Name, 
        x.Name, 
        (x.GetCustomAttribute(typeof(DisplayAttribute)) is DisplayAttribute displayAttribute) ? displayAttribute.Name : null 
    })
    .ToList();
}

Test

List<List<string>> mebmers = GetMembers(typeof(Teacher));

Result :

foreach(var item in mebmers)
{
   Console.WriteLine(string.Join(",", item));
}

I hope that will help you out.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow