Reputation: 5738
I am not sure how to word this question properly, so apologies at the very beginning.
I am working with MongoDb and at some point, I need to design a lambda expression as follows:
...Set(g => g.Profile.First_Name, "Test");
Now, g
refers to a class called User
, which has a property of type Profile
(a different class), with the same name Profile
. As you can see, in the lambda expression, I am selecting the First_Name
property and then passing the value "Test"
to it.
My Question: Is there a way to select the property by name?
In more detail - is something like this possible? :
.... g.Profile. ("First_Name")
As I am typing this, even to me it sounds ridiculous, but I need to dynamically select the particular properties therefore I need to select them via their names.
How do I actually achieve this?
I tried :
g.Profile.GetType().GetProperty("First_Name")
But it doesn't seem to be equivalent to g.Profile.First_Name
.
Any ideas on what can be done?
Upvotes: 2
Views: 754
Reputation: 149020
I probably don't actually want to use reflection here.
The g => ...
is not actually a lambda function, but an expression tree — it's some fancy syntactic sugar for describing a process, in this case, a process for getting a certain property given a record of type User
. MongoDB API provides overloads that allow expression so you can code 90% of your operations more gracefully, but if you really need to be dynamic you can of course bypass this, for example:
var setName = Builders<User>.Update.Set(g => g.Profile.First_Name, "Test");
Is roughly equivalent to something like:
var setName = Builders<User>.Update.Set("profile.first_name", "Test");
Of course, if you have BsonProperty
attributes on your properties, custom conventions, etc. that can change the path of the BSON being updated.
Now, suppose you don't want to have to hard-code the BSON paths. Well, you can generate dynamic expression trees, but it's not very elegant or performant. You'd use something along the lines of this:
ParameterExpression param = Expression.Parameter(typeof(User), "g");
Expression<Func<User, String>> expr =
Expression.Lambda<Func<User, String>>(
Expression.Property(
Expression.Property(
param,
"Profile"
),
"First_Name"
),
new[] { param }
);
var setName = Builders<User>.Update.Set(expr, "Test");
Upvotes: 3