用linq到实体的concat字符串

时间:2013-03-07 17:14:39

标签: c# .net entity-framework-5 dynamic-linq

我正在使用Dynamic LinqLinq to Entities

所以,我用这段代码测试了正常List<Person>,一切正常:

 List<Person> per = new List<Person>();
 per.Add(new Person { IdNo = "1", LastName = "test", MiddleName = "go", FirstName = "let" });
 per.Add(new Person { IdNo = "2", LastName = "hope", MiddleName = "is", FirstName = "way" });
 per.Add(new Person { IdNo = "3", LastName = "must", MiddleName = "be", FirstName = "human" });
 per.Add(new Person { IdNo = "4", LastName = "thing", MiddleName = "anywhere", FirstName = "can" });
 per.Add(new Person { IdNo = "5", LastName = "bird", MiddleName = "fly", FirstName = "away" });

 List<object> paramObjects = new List<object>();
 List<string> fields = new List<string>();
 fields.Add("IdNo == @0");
 paramObjects.Add("1");

 fields.Add("or (LastName + \", \" + MiddleName + \" \" + FirstName).Contains(@1)");
 paramObjects.Add("m");

 var where = string.Join(" ", fields.ToArray());
 var toParam = paramObjects.ToArray();

 var query = per.AsQueryable().Where(where, toParam).ToList();

当我进入Linq To Entities时。

using(var con = new DbContext())
{
   var query = con.Person.Where(where, toParam).ToList();
}

我收到了这个错误:

  

LINQ to Entities无法识别方法'System.String   Concat(System.Object,System.Object)'方法,而这个方法不行   被翻译成商店表达。

我的问题是:

如何使用 Dynamic Linq 在我的示例中使用Concat基础Linq To Entities字符串?有人可以帮帮我吗?

3 个答案:

答案 0 :(得分:4)

  • 选项1:

    更改行...

    fields.Add("or (LastName + \", \" + MiddleName + \" \" + FirstName).Contains(@1)");
    

    ...至

    fields.Add("or string.Concat(LastName, \", \", MiddleName, \" \", FirstName).Contains(@1)");
    
  • 选项2:

    打开Dynamic LINQ库的Dynamic.cs文件,在该文件中搜索"GenerateStringConcat"。你应该找到这个方法:

    Expression GenerateStringConcat(Expression left, Expression right) {
        return Expression.Call(
            null,
            typeof(string).GetMethod("Concat",
                new[] { typeof(object), typeof(object) }),
            new[] { left, right });
    }
    

    object参数类型更改为string,即:

    Expression GenerateStringConcat(Expression left, Expression right) {
        return Expression.Call(
            null,
            typeof(string).GetMethod("Concat",
                new[] { typeof(string), typeof(string) }),
            new[] { left, right });
    }
    

请记住,Dynamic LINQ不是一个特殊的“LINQ到实体库”,而是IQueryable的通用库。可能有可查询提供程序支持string.Concat(object, object)一般object参数,但LINQ到实体不支持。它仅支持string的{​​{1}}参数版本。在实际调用string.Concat时查看动态LINQ文件(仅​​一次)我相信只要您只想将库与LINQ-to-Entities / Entity Framework一起使用,上述更改就是安全的。

修改

选项1不起作用,因为GenerateStringConcat在示例中获得了超过四个字符串参数。它最多只能处理四个参数,因为Concat具有四个显式string.Concat参数的重载。似乎不可能在Dynamic LINQ中使用带有数组参数string的重载。

答案 1 :(得分:1)

我有同样的问题但是使用NHibernate,我的解决方案是修改GenerateStringConcat方法

我改变了这个:

static Expression GenerateStringConcat(Expression left, Expression right)
    {   
        return Expression.Call(
            null,
            typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) }),
            new[] { left, right });
    }

为此:

static Expression GenerateStringConcat(Expression left, Expression right)
    {            
        return Expression.Add(
            left,
            right,
            typeof(string).GetMethod("Concat", new[] { typeof(object), typeof(object) })
        );
    }

他工作得很好:)。

答案 2 :(得分:0)

更改

 var where = string.Join(" ", fields.ToArray());

string where = string.Empty;
foreach(var f in fields)
{
    where += f + " "; 
}

where = where.Trim();