【问题标题】:Help with Linq and Generics. Using GetValue inside a Query帮助 Linq 和泛型。在查询中使用 GetValue
【发布时间】:2010-12-28 13:37:19
【问题描述】:

我正在尝试创建一个函数,将“where”子句添加到基于属性和值的查询中。这是我的函数的一个非常简单的版本。

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

错误消息是:LINQ to Entities 无法识别方法“System.Object CompareObjectEqual(System.Object, System.Object, Boolean)”方法,并且该方法无法转换为存储表达式。

看起来不能在 linq 查询中使用 GetValue。我可以通过其他方式实现吗?

在 C#/VB 中发布您的答案。选择让您感觉更舒适的那个。

谢谢

编辑:我也试过这段代码,结果相同

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

【问题讨论】:

    标签: vb.net linq generics linq-to-entities


    【解决方案1】:

    您需要将代码转换为表达式树。

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

    【讨论】:

    • 你好汤姆。您能否提供链接或简要说明为什么它可以与表达式树一起使用但不能直接与 lambda 一起使用?
    【解决方案2】:

    您是否尝试过退出 DirectCast 并改为反映 lambda 参数?像这样的:

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

    我不确定你甚至可以在 lambda 中做这种事情,但值得一试。

    【讨论】:

    • 我用同样的错误尝试了这个:query = query.Where(Function(c) c.GetType().GetProperty("Id").GetValue(c, Nothing).Equals(PValue )) '''我在这里使用了一个我知道存在的属性名称来简化
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多