查询实体LINQ使用Dyanmic字段名称 [英] Querying Entity with LINQ using Dyanmic Field Name

查看:357
本文介绍了查询实体LINQ使用Dyanmic字段名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经创造了ASP.NET MVC动态搜索屏幕。我从通过反射实体检索的字段名,这样我可以允许用户选择哪些领域,他们希望,而不是搜索显示视图中的所有字段上。



当搜索结果发布回控制器,我收到一封包含字段名和值的FormCollection。我不知道有多少字段被搜索上,并且的FormCollection仅包含由用户分别选择了字段。



我希望能够现在就采取该字段名称并应用到我的LINQ语句时,我查询例如数据库:

 公开名单<人与GT; SearchPeople(词典<字符串,字符串> fieldValueDictionary)
{
名单,LT;人>的SearchResult =新的List<人与GT;();

的foreach(在fieldValueDictionary.Keys字符串键)
{
searchResults.Add(entities.People.Where(P => P<使用密钥字符串作为字段名> == fieldValueDictionary [关键]));
}

返回的SearchResult;
}



在那里我有使用密钥字符串作为字段名,它会像p => p.FirstName == fieldValueDictionary [关键]其中键=名字。我已经尝试和失败使用Lambda表达式树,并曾与动态LINQ一点成绩。唯一的选择就是做这样的事情:

 公开名单<人与GT; SearchPeople(词典<字符串,字符串> fieldValueDictionary)
{
&IQueryable的LT;人>结果= entities.People;

的foreach(在fieldValueDictionary.Keys字符串键)
{
开关(K),
{
案姓:结果= results.Where( entities.People.Where(p => p.FirstName == K);
案姓氏:成绩= results.Where(entities.People.Where(p => p.LastName == K) ;
//重复表
}
}

返回results.ToList<全部26个领域;人与GT;();
}

更新:我已经做了研究,Lambda表达式树通过以下职位:



的http://计算器。 COM /问题/ 1667813 /动态地创建-lambda表达式表达式 - LINQ的orderbydescending



http://stackoverflow.com/questions/903558/parameter-problem-with-expression-lambda



HTTP: //stackoverflow.com/questions/1299534/linq-passing-lambda-expression-as-parameter-to-be-executed-and-returned-by-metho



我已经尽量让一个lambda输出得到如下:p => p.FirstName,但我不能得到这个在那里工作。有什么建议么?我的代码如下:

 的MemberInfo成员= typeof运算(人).GetProperty(名字); 
ParameterExpression cParam = Expression.Parameter(typeof运算(人),P);
表达体= Expression.MakeMemberAccess(cParam,成员);

VAR波长= Expression.Lambda(身体,cParam);


解决方案

更​​大量的试验和错误和搜索我意外后发现了另一个SO贴子,讨论了同样的问题:



出现InvalidOperationException:没有方法上键入'在哪里'System.Linq.Queryable与提供的参数


$兼容b $ b

下面是我修改后的代码的作品:

 的IQueryable查询= entities.People; 
类型[] = exprArgTypes {query.ElementType};

串propToWhere =名字;

ParameterExpression P = Expression.Parameter(typeof运算(人),P);
MemberExpression成员= Expression.PropertyOrField(P,propToWhere);
LambdaExpression波长= Expression.Lambda<&Func键LT;人,布尔>>(Expression.Equal(成员,Expression.Constant(斯科特)),P);

MethodCallExpression methodCall = Expression.Call(typeof运算(可查询),去哪儿,exprArgTypes,query.Expression,拉姆达);

IQueryable的Q = query.Provider.CreateQuery(methodCall);



对于一些希望很容易修改,我应该能够得到这个与任何类型的工作。



再次感谢您的回答阿尼和放大器;约翰·博文


I have created a dynamic search screen in ASP.NET MVC. I retrieved the field names from the entity through reflection so that I could allow the user to choose which fields they wanted to search on instead of displaying all fields in the view.

When the search result is Posted back to the controller, I receive a FormCollection containing the FieldName and the Value. I don't know how many fields are being searched on, and the FormCollection only contains fields that were chosen by the user.

I want to be able to now take that field name and apply that to my LINQ statement when I query the database for example:

public List<People> SearchPeople(Dictionary<string, string> fieldValueDictionary)
{
    List<People> searchResults = new List<People>();

    foreach (string key in fieldValueDictionary.Keys)
    {
         searchResults.Add(entities.People.Where(p => p.<use the key string as the fieldName> == fieldValueDictionary[key]));
    }

    return searchResults;
}

Where I have "use the key string as the fieldName" it would be like p => p.FirstName == fieldValueDictionary[key] where key = "FirstName". I've tried and failed to use Lambda Expression Trees, and have had a little success with Dynamic LINQ. The only other alternative is to do something like:

public List<People> SearchPeople(Dictionary<string, string> fieldValueDictionary)
{
    IQueryable<People> results = entities.People;

    foreach (string key in fieldValueDictionary.Keys)
    {
         switch (k)
         {
             case "FirstName": results = results.Where(entities.People.Where(p => p.FirstName == k);
             case "LastName": results = results.Where(entities.People.Where(p => p.LastName == k);
             // Repeat for all 26 fields in table
         }
    }

    return results.ToList<People>();
}

UPDATE: I've done research into Lambda Expression Trees through the following posts:

http://stackoverflow.com/questions/1667813/dynamically-create-lambdas-expressions-linq-orderbydescending

http://stackoverflow.com/questions/903558/parameter-problem-with-expression-lambda

http://stackoverflow.com/questions/1299534/linq-passing-lambda-expression-as-parameter-to-be-executed-and-returned-by-metho

I've gotten as far as getting a lambda to output the following: "p => p.FirstName", but I can't get this to work in a where. Any Suggestions? My code is below:

MemberInfo member = typeof(People).GetProperty("FirstName");
ParameterExpression cParam = Expression.Parameter(typeof(People), "p");    
Expression body = Expression.MakeMemberAccess(cParam, member);        

var lambda = Expression.Lambda(body, cParam);

解决方案

After a lot more trial and error and searching I accidentally found another SO post that covers the same issue:

InvalidOperationException: No method 'Where' on type 'System.Linq.Queryable' is compatible with the supplied arguments

Here is my modified code that works:

        IQueryable query = entities.People;
        Type[] exprArgTypes = { query.ElementType };

        string propToWhere = "FirstName";            

        ParameterExpression p = Expression.Parameter(typeof(People), "p");
        MemberExpression member = Expression.PropertyOrField(p, propToWhere);
        LambdaExpression lambda = Expression.Lambda<Func<People, bool>>(Expression.Equal(member, Expression.Constant("Scott")), p);                            

        MethodCallExpression methodCall = Expression.Call(typeof(Queryable), "Where", exprArgTypes, query.Expression, lambda);

        IQueryable q = query.Provider.CreateQuery(methodCall);

With some hopefully pretty easy modifications, I should be able to get this to work with any type.

Thanks again for your answers Ani & John Bowen

这篇关于查询实体LINQ使用Dyanmic字段名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆