C# - How to set builder.Property().HasComment dynamically in a model in Entity Framework Core 3.1

Viewed 459

I'm trying to apply builder.Property(_ => _.[DYNAMIC_FIELD_NAME]).HasComment("Some comment") data to all of the properties that have Description attribute in a model. So far here's my attempt using reflection:

public class User : TableFieldsBase, IEntityTypeConfiguration<User>
{
    public void Configure(EntityTypeBuilder<User> builder)
    {
        var tableName = this.GetType().Name;
        builder.ToTable(tableName);
        
        var props = GetType().GetProperties();
        foreach(var prop in props)
        {
            var descriptionAttr = this.GetAttributeFrom<DescriptionAttribute>(prop.Name);
            if(descriptionAttr != null)
            {
                builder.Property(t => EF.Property<object>(t, prop.Name)).HasComment(descriptionAttr.Description);
            }
        }
    }

    [Description("This is the username")]
    public string Username { get; set; }
    
    [DisplayName("Email")]
    public string Email { get; set; }
}

As you can see I'm looping through all of the properties of the model and extracting their description text. For example Username has a description attribute that I wanna use to save that in the "comment" field within my database. The issue here I'm not sure how to apply the property dynamically within builder.Property method. Maybe I'm looking at it in a wrong way?

This is the error I'm getting when I run this code:

Exception has occurred: CLR/System.ArgumentException
Exception thrown: 'System.ArgumentException' in Microsoft.EntityFrameworkCore.dll: 'The expression 't => Property(t, value(Backend.Classes.Api.Avpf.Core.Models.User+<>c__DisplayClass0_0).prop.Name)' is not a valid property expression. The expression should represent a simple property access: 't => t.MyProperty'.'
   at Microsoft.EntityFrameworkCore.Infrastructure.ExpressionExtensions.GetPropertyAccess(LambdaExpression propertyAccessExpression)
   at Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder`1.Property[TProperty](Expression`1 propertyExpression)
   at Backend.Classes.Api.Avpf.Core.Models.User.Configure(EntityTypeBuilder`1 builder) in Models\User.cs:line 38

Thanks in advance.

1 Answers

Simply use the Property method overload with string propertyName argument:

builder.Property(prop.Name)
    .HasComment(descriptionAttr.Description);
Related