Get parent property from Expression function

So, let's say that I have the following classes:

public class Model {
    public AnotherModel InnerModel {
        get;
        set;
    }
}

public class AnotherModel {
    public String Value{
        get;
        set;
    }
}

      

I now have the following function:

public static void Foo<T, U>(Expression<Func<T, U>> func) {
     // Get the property info from func
}

      

Now I would like to do the following:

Foo<Model, String>(o => o.InnerModel.Value)

      

Here's the problem:

I know that you can get PropertyInfo from func expression by doing:

PropertyInfo propertyInfo = (PropertyInfo)((MemberExpression)func.Body).Member;

      

This will give me the PropertyInfo of the Value property. However, I would also like to get information about the parent property, that is, the InnerModel property.

What I know so far is that I can do the following:

((MemberExpression)func.Body).Expression

      

to get information about the parent property. However, there seems to be no way to extract the PropertyInfo from the expression itself.

Is there any way to get the PropertyInfo expression?

Edit: To clarify, and this might be a bad way to try, but here goes: I can't use EntityFramework to do this, just to make sure it's clear.

There is a database that I need to communicate with via the API.

This database got the usual relationships like: The table thread UserID -> Users.UserID

Now let's select the models. To follow the example above:

class Thread {
    [Reference(USER_USERID)]
    [TableKey(THREAD_USERID)]
    public User user {
        get;set;
    }
}

class User {
     [TableKey(USER_USERID)]
     public int UserId {
         get;set;
     }
}

      

Now I would like to make requests for this. So I thought, "Hey, let's use expressions to make it easier for the end user to ask for things, yay."

So, we could do something like EqualTo (o => o.user.UserId, 1);

However, since the TableKey property is different from the reference key, I need to first fetch the userId from the Thread table from the database, and then with that Id start querying the User table for information with that ID.

Perhaps this clarifies the purpose of all this, or maybe not.

+3


source to share


1 answer


As you have already defined, the body of the expression is a MemberExpression. There are two properties of the MemberExpression that we need to look at.

The first property is Member. This is the MemberInfo being called. In your example, this is the Value property. The second property that we need to consider is the Expression property. This is what the member expression is called upon. In your example, this is {o.InnerModel}.

{o.InnerModel} is another MemberExpression. The member is InnerModel and the expression is o.

Here is some code to get the MemberInfos chain

public static void Foo<T, U>(Expression<Func<T, U>> func)
{
    var memberExp = func.Body as MemberExpression;
    while (memberExp != null)
    {
        var memberInfo = memberExp.Member;
        Console.WriteLine(memberInfo.Name);
        memberExp = memberExp.Expression as MemberExpression;
    }
}

      

When called like this:

Foo<Model, String>(o => o.InnerModel.Value);

      



it will output:

  • Value
  • InnerModel

It:

Foo<Assembly, int>(a => a.EntryPoint.DeclaringType.AssemblyQualifiedName.Length);

      

will output:

  • Length
  • AssemblyQualifiedName
  • DeclaringType
  • EntryPoint
+2


source







All Articles