How to get Linq expression values

I have a method that takes an expression type parameter, in my method I want to get the values โ€‹โ€‹of this expression, but I canโ€™t find it hot to do this.

private User GetUser(Expression<Func<User, bool>> query) { User user = Context.User.Where(query).FirstOrDefault(); return user; } 

I call this method with various parameters, for example

 GetUser(u => u.Username == username); GetUser(u=> u.Email == email); 

I want to change the GetUser method to work with stored procedures, but I need to find what is inside the request parameter

I want to check if the request is u.Username == username I will call GetUserByUsername SP if the request is u.Email == email I will call GetuserByEmail SP

+4
source share
4 answers

An expression can be reduced to several expressions.

  var body = query.Body as BinaryExpression; if (body != null) { var left = body.Left as MemberExpression; if (left != null) { Console.WriteLine(left.Member.Name); // You can get "Username" or "Email" here } } 

By the way, I think you're in the wrong direction. Think about this situation: some other developers see your GetUser method using it as follows:

 var result = GetUser(u => u.Email.Equals(" abc@foo.com ")); //or var another = GetUser(u => u.Username.Contains("bar")); 

He will think that he is right, but in fact your method will not give his ideal result! Well, you can say โ€œit doesn't matter, I will let them know about this changeโ€, but what about the fact that after you left this team / company? This is a nightmare if the method does not behave like its declaration.

+3
source

Perhaps you should use LINQ for SQL. It does exactly what you want: tear apart the expression and see what fields and comparisons you need. I do not propose doing this manually, but if you want, look at the members of the Expression class, this is an expression tree and will have nodes, such as access to properties and comparisons.

+1
source

You could theoretically go through the expression tree in query.Body to determine the intent of the function - in this case it will be a BinaryExpression in which you will need to check the Left and Right properties to see what is being compared.

However, I would suggest that if you use special SPs to execute the request, then using the expression is actually not the case - creating separate GetUserByUsername and GetUserByEmail will be more reliable if you really want to throw exceptions when someone calls GetUser with unexpected expression.

+1
source

Where accepts a Func<TSource, bool> predicate, not Expression . Check out an example:

 class Program { private static List<int> l = new List<int> { 1, 2, 3, 4, 5 }; static void Main(string[] args) { Console.WriteLine(GetNum(x => x > 3)); Console.ReadKey(); } private static int GetNum(Func<int, bool> predicate) { return l.Where(predicate).FirstOrDefault(); } } 

It returns 4. So, change the function definition to private User GetUser(Func<User, bool> query)

0
source

Source: https://habr.com/ru/post/1333199/


All Articles