1

我正在尝试执行以下通用方法来搜索数据库中的实体:

    // 'atributo' is the name of the attribute to search against
    public List<TEntity> buscar<TEntity>(string valor, string atributo) where TEntity : class
    {
        var matches = from m in db.Set<TEntity>()
                      where m.GetType().GetProperty(atributo).GetValue(m, null).ToString().Contains(valor)
                      select m;

        return matches.ToList();
    }

当然我得到了例外:

LINQ to Entities 无法识别方法“System.String ToString()”方法

而且我知道 GetType()、GetProperty() 和 GetValue() 也是无效的 LINQ 方法。

我无法弄清楚如何在查询之前使用无效方法。

有任何想法吗?

TIA

4

3 回答 3

4

您可以自己编写表达式树(动态 LINQ 对于您的需要来说太过分了):

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;

class YourClass
{
    public static List<TEntity> DoSomething<TEntity>(DbContext db, string valor, string atributo)
        where TEntity : class
    {
        var mParam = Expression.Parameter(typeof(TEntity));

        var matches = db.Set<TEntity>()
                        .Where(Expression.Lambda<Func<TEntity, bool>>(
                            Expression.Call(
                                Expression.Convert(
                                    Expression.Property(mParam, atributo),
                                    typeof(String)
                                    ),
                                "Contains",
                                new Type[0],
                                Expression.Constant(valor)
                                ),
                            mParam
                         ));

        return matches.ToList();
    }
}

笔记:

  1. 如果该属性未在 TEntity 上定义,那将不起作用(即使 TEntity 是抽象的并且所有子类定义了该属性);
  2. 如果已知属性的返回类型为String,则可以避免Expression.Convert调用;
  3. 如果 Entity Framework 不能将属性的值转换为字符串(例如,如果属性返回实体类型),这将不起作用;
于 2013-01-30T08:23:11.183 回答
0

linq to entity 将 linq 转换为表达式树,然后尝试将该表达式树转换为 SQL。它不评估表达式,因此不能将反射代码转换为 SQL。您可以做的是使用动态 linq,您的代码将类似于

public List<TEntity> buscar<TEntity>(string valor, string atributo) where TEntity : class
{
    return db.Set<TEntity>()
           .Where(atributo + =".Contains(\"" + valor + "\")")
           .ToList()
}
于 2013-01-30T07:52:57.340 回答
-1

更新:

SqlFunctions.StringConvert(m.GetType().GetProperty(atributo).GetValue(m, null))
于 2013-01-30T07:23:32.890 回答