Get parent property from Expression function

柔情痞子 提交于 2021-01-27 05:49:01

问题


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;
    }
}

Now I have the following function:

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

What I would like to do now is the following:

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

Here comes the problem:

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

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

This will get 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 fetch information of the parent property. However, it doesn't seem to be possible to extract a PropertyInfo from the Expression itself.

Is there some way of actually retrieving the PropertyInfo of the Expression?

Edit: To clarify, and it might be a bad way of attempting it but here goes: I can't use EntityFramework for this, just to make sure that that is understood.

There is a database which I need to communicate with through an API.

This database got the usual relations like the manner: Table Thread UserID -> Users.UserID

This now extract to models. To follow the above example:

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 queries to this. So I thought "Hey, let's use expressions to simplify for the end user on how to ask for stuff, yay."

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

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

Maybe this clarifies the purpose of all this, or maybe it don't.


回答1:


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

The first is the Member property. This the MemberInfo being called. In your example this the Value property. The second property that we need to look at is the Expression property. This is what the member expression is being called on. 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 chain of MemberInfos

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

This:

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

will output:

  • Length
  • AssemblyQualifiedName
  • DeclaringType
  • EntryPoint


来源:https://stackoverflow.com/questions/26890205/get-parent-property-from-expression-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!