2013-03-07 74 views
1

我使用的是Dynamic LinqLinq to Entities的毗连字符串使用LINQ到实体

所以,我测试的正常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 does not recognize the method 'System.String Concat(System.Object, System.Object)' method, and this method cannot be translated into a store expression.

我的问题是:

如何使用动态的LINQ使用Linq To Entities基地在我的例子Concat字符串?任何人都可以帮助我?

+0

你试过'ToString()'? – 2013-03-07 17:19:25

+0

是不是像'(LastName + \“,\”+ MiddleName + \“\”+ FirstName).ToString()。含有(@ 1)'这将是错误→'LINQ to Entities不能识别该方法'System.String ToString()'' – spajce 2013-03-07 17:25:01

+0

不,我的意思是'“或(LastName.ToString()+ \”,\“+ LastName.ToString()+ \”\“+ LastName.ToString())。Contains @ 1)“' – 2013-03-07 17:26:40

回答

4
  • 选项1:

    更改行...

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

    ......到

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

    打开Dynamic.cs文件动态LINQ库,搜索该文件"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 }); 
    } 
    

请记住,动态LINQ是不是一个特殊的“LINQ到实体图书馆“,但为IQueryable的通用图书馆。可能有Queryable提供程序支持string.Concat(object, object),但其中的参数为object,但LINQ-to-Entities不支持。它仅支持string参数版本string.Concat。实际调用GenerateStringConcat时只查看动态LINQ文件(只有一次)我相信上面的更改是安全的,只要您只希望将该库用于LINQ-to-Entities/Entity Framework。

编辑

选项1不起作用,因为Concat获取的例子超过字符串参数。它只能运行四个参数,因为string.Concat有四个明确的string参数过载。Dynamic LINQ中的数组参数params string[]似乎无法使用过载。

+0

谢谢先生,但不幸的是,_option 1:不工作_错误是'没有适用的方法'Concat'存在'String''类型中,我会尝试选项2. – spajce 2013-03-07 18:09:43

+0

刚应用了_option 2._错误仍然存​​在''String''没有适用的方法'Concat'存在 – spajce 2013-03-07 18:17:00

+1

@spajce:对你的第一个评论:对不起,我只用三个参数测试,而不是用五个,就像你的例子。选项1不能使用五个参数(请参阅编辑我的答案)。对您的评论2:当您使用选项2时,请使用您的原始查询字符串与“+”连接,而不是查询字符串中显式的“string.Concat(...)”。 – Slauma 2013-03-07 18:22:49

0

变化

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

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

where = where.Trim(); 
+0

即使我们不会使用它,我对'string.Join'没有任何问题,错误仍然发生。 – spajce 2013-03-07 17:28:45

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

他已经做得很不错:)