mercredi 30 juin 2021

C# - Create Complete Dynamic Expression Trees from PropertyInfo [duplicate]

I have already been through the following links, but none of them seems to answer my question-

  1. Create Expression from PropertyInfo
  2. Dynamically Create Expression from PropertyInfo
  3. Creating dynamically Expression<Func<T,Y>>

Basically I asked this question earlier today and comment from abdusco help me solve it in the following manner-

protected override void OnModelCreating(ModelBuilder builder)
{
    //Remove pluralizing table name convention (Install package - Microsoft.EntityFrameworkCore.Relational)
    foreach (var entity in builder.Model.GetEntityTypes())
    {
        entity.SetTableName(entity.DisplayName());
    }

    // Following properties belongs to User.cs and are non-public (internal).
    builder.Entity<User>().Property(x => x.FirstName);
    builder.Entity<User>().Property(x => x.MiddleName);
    builder.Entity<User>().Property(x => x.LastName);
    builder.Entity<User>().Property(x => x.EmailId);
    builder.Entity<User>().Property(x => x.DateOfBirth);

    base.OnModelCreating(builder);
}

But I believe above-mentioned approach is going to be very cumbersome, as there will be several classes similar to User.cs in the namespace: Components.User.Persistance.Poco. I am now trying to achieve the above-mentioned solution as follows-

private void AddNonPublicPropertiesToTheModel()
{
    // I have hard-coded the namespace for now, but it will be supplied as a parameter.
    var types = GetAllMembersOfNamespaceOfExecutingAssembly("Components.User.Persistance.Poco");
    foreach (var type in types)
    {
        foreach (var propertyInfo in GetNonPublicInstancePropertyInfo(type))
        {
            var parameter = Expression.Parameter(type);
            var property = Expression.Property(parameter, propertyInfo);
            var conversion = Expression.Convert(property, typeof(object));
            //var lambda = Expression.Lambda<Func<, object>>
        }
    }
}

private static PropertyInfo[] GetNonPublicInstancePropertyInfo(Type type) =>
    type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);

private static Type[] GetAllMembersOfNamespaceOfExecutingAssembly(string namespaceName) =>
    GetAllMembersOfNamespace(namespaceName, Assembly.GetExecutingAssembly());

private static Type[] GetAllMembersOfNamespace(string namespaceName, Assembly assembly) =>
    assembly
        .GetTypes()
        .Where(type => string.Equals(type.Namespace, namespaceName, StringComparison.Ordinal))
        .ToArray();

Question- How do I generate - builder.Entity<User>().Property(x => x.FirstName);, using all this reflection? Or if you have a better approach altogether, please feel free to share.
NOTE:- Please go through the following question to get a broader view of what I am trying to achieve.





Aucun commentaire:

Enregistrer un commentaire