将带有linq的字符串连接到实体

本文关键字:连接 实体 字符串 linq | 更新日期: 2023-09-27 18:02:43

我使用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。字符串Concat(系统。Object, System.Object)'方法,而此方法不能翻译成store表达式

我的问题是:

如何Concat字符串使用Linq To Entities基地在我的例子中使用动态Linq?有人能帮我吗?

将带有linq的字符串连接到实体

  • 选项1:

    换行…

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

    fields.Add("or string.Concat(LastName, '", '", MiddleName, '" '", FirstName).Contains(@1)");
    

  • 选项2:

    打开动态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 });
    }
    

请记住,动态LINQ不是一个特殊的"LINQ到实体库",而是IQueryable的通用库。可能有Queryable提供程序支持string.Concat(object, object)和一般的object参数,但是LINQ-to-Entities不支持。仅支持string.Concatstring参数版本。查看动态LINQ文件时,GenerateStringConcat实际上被调用(只有一次),我相信上面的变化是安全的,只要你只想使用LINQ到实体/实体框架库。

编辑

选项1不起作用,因为Concat在示例中获得了超过四个字符串参数。它最多只能工作四个参数,因为string.Concat有一个带有四个显式string参数的重载。在动态LINQ中,似乎不可能与数组参数params string[]一起使用重载。

我有同样的问题,但与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) })
        );
    }

他工作得很好

变化

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

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