Help with Linq and Generics. Using GetValue Inside a Request

I am trying to make a function that adds a "where" clause to a query based on property and value. This is a very simple version of my function.

Private Function simplified(ByVal query As IQueryable(Of T), ByVal PValue As Long, ByVal p As PropertyInfo) As ObjectQuery(Of T) query = query.Where(Function(c) DirectCast(p.GetValue(c, Nothing), Long) = PValue) Dim t = query.ToList 'this line is only for testing, and here is the error raise Return query End Function 

Error message: LINQ to Entities does not recognize the method 'System.Object CompareObjectEqual (System.Object, System.Object, Boolean)', and this method cannot be translated into a storage expression.

It seems like it cannot use GetValue inside the linq query. Can I achieve this differently?

Post your answer in C # / VB. Choose the one that makes you feel more comfortable.

thanks

EDIT : I also tried this code with the same results

 Private Function simplified2(ByVal query As IQueryable(Of T)) query = From q In query Where q.GetType.GetProperty("Id").GetValue(q, Nothing).Equals(1) Select q Dim t = query.ToList Return query End Function 
+3
source share
2 answers

You need to convert the code to an expression tree.

 using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; namespace WindowsFormsApplication1 { static class Program { [STAThread] static void Main() { using (var context = new NorthwindEntities()) { IQueryable<Customer> query = context.Customers; query = Simplified<Customer>(query, "CustomerID", "ALFKI"); var list = query.ToList(); } } static IQueryable<T> Simplified<T>(IQueryable<T> query, string propertyName, string propertyValue) { PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName); return Simplified<T>(query, propertyInfo, propertyValue); } static IQueryable<T> Simplified<T>(IQueryable<T> query, PropertyInfo propertyInfo, string propertyValue) { ParameterExpression e = Expression.Parameter(typeof(T), "e"); MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo); ConstantExpression c = Expression.Constant(propertyValue, propertyValue.GetType()); BinaryExpression b = Expression.Equal(m, c); Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(b, e); return query.Where(lambda); } } } 
+6
source

Did you try to pull out DirectCast and instead affect the lambda parameter? Something like that:

 query.Where(Function(c) _ c.GetType().GetProperty(p, GetType("Int64")).GetValue(c, Nothing) = PValue) 

I'm not sure you can even do such things in lambda, but it's worth it.

0
source

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


All Articles