C# 如何将字典的LINQ表达式扩展为参数
我有一个程序,我扩展了LINQ表达式,使用任何属性名和值作为参数得到结果。我的扩展只适用于一个属性,但是我需要查找并传递两个或多个属性作为过滤器。有人能帮我延长我的LINQ吗?下面是我的代码实现。我使用了控制台应用程序 基于我刚刚调用的用户列表的示例代码C# 如何将字典的LINQ表达式扩展为参数,c#,linq,C#,Linq,我有一个程序,我扩展了LINQ表达式,使用任何属性名和值作为参数得到结果。我的扩展只适用于一个属性,但是我需要查找并传递两个或多个属性作为过滤器。有人能帮我延长我的LINQ吗?下面是我的代码实现。我使用了控制台应用程序 基于我刚刚调用的用户列表的示例代码 GetByPropertyName("PropertyName", "Value"); 比如说 var user = GetByPropertyName("FirstName", "James"); Program.cs using Sys
GetByPropertyName("PropertyName", "Value");
比如说
var user = GetByPropertyName("FirstName", "James");
Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static List<User> _users = new List<User>();
static void Main(string[] args)
{
var users = new List<User> {
new User { FirstName = "John", MiddleName = "Hall", LastName = "Long", Email="john.long@gmail.com"},
new User { FirstName = "John", MiddleName = "Wine", LastName = "Crawford", Email="john.crawford@gmail.com" },
new User { FirstName = "James", MiddleName = "Cage", LastName = "Hall", Email="james.hall@hotmail.com" },
new User { FirstName = "Larry", MiddleName = "Wine", LastName = "Crawford", Email="larry.crawford@gmail.com" },
new User { FirstName = "Jennifer", MiddleName = "Wine", LastName = "Long", Email="jennifer.long@gmail.com"}
};
//works okay for one property name
_users = users;
var user = GetByPropertyName("FirstName", "James");
//works okay for one property name
_users = users;
var user1 = GetByPropertyName("Email", "james.hall@hotmail.com");
//NEED HELP
//For GetByPropertyNames two or more properties
var filters = new Dictionary<object, object>();
filters.Add("FirstName", "John");
filters.Add("Email", "john.long@gmail.com");
var user2 = GetByPropertyNames(filters);
}
public static User GetByPropertyName(object propertyName, object value)
{
var result = _users.AsQueryable().Where(propertyName.ToString(), value).FirstOrDefault();
return result;
}
public static User GetByPropertyNames(Dictionary<object, object> filters)
{
var result = _users.AsQueryable().Where(filters).FirstOrDefault();
return null;
}
}
public class User
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace ConsoleApplication1
{
public static class Extensions {
public static IQueryable<T> Where<T>(this IQueryable<T> source, string propertyName, object value) {
return (IQueryable<T>)Where((IQueryable)source, propertyName, value);
}
public static IQueryable Where(this IQueryable source, string propertyName, object value) {
var x = Expression.Parameter(source.ElementType, "x");
var selector = Expression.Lambda(
Expression.Equal(
Expression.PropertyOrField(x, propertyName),
Expression.Constant(value)
), x
);
return source.Provider.CreateQuery(
Expression.Call(typeof(Queryable), "Where", new Type[] { source.ElementType }, source.Expression, selector)
);
}
//NEED HELP
//TO DO
public static IQueryable<T> Where<T>(this IQueryable<T> source, Dictionary<object, object> filters)
{
return (IQueryable<T>)Where((IQueryable)source, filters);
}
public static IQueryable Where(this IQueryable source, Dictionary<object, object> filters)
{
var x = Expression.Parameter(source.ElementType, "x");
//NEED HELP
//expression for _users.FirstOrDefault(x=>x.Filter1==Filter1Value && x.Filter2==Filter2Value && so on and so fort depends on how many filters are passed as arguments);
//var selector = Expression.Lambda(
// Expression.Equal(
// Expression.PropertyOrField(x, propertyName),
// Expression.Constant(value)
// ), x
//);
//return source.Provider.CreateQuery(
// Expression.Call(typeof(Queryable), "Where", new Type[] { source.ElementType }, source.Expression, selector)
//);
//remove line below
return null;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Linq.Expressions;
使用系统文本;
使用System.Threading.Tasks;
命名空间控制台应用程序1
{
班级计划
{
静态列表_users=新列表();
静态void Main(字符串[]参数)
{
var users=新列表{
新用户{FirstName=“John”,MiddleName=“Hall”,LastName=“Long”,Email=“John”。long@gmail.com"},
新用户{FirstName=“约翰”,MiddleName=“葡萄酒”,LastName=“克劳福德”,Email=“约翰。crawford@gmail.com" },
新用户{FirstName=“James”,MiddleName=“Cage”,LastName=“Hall”,Email=“James”。hall@hotmail.com" },
新用户{FirstName=“Larry”,MiddleName=“Wine”,LastName=“Crawford”,Email=“Larry”。crawford@gmail.com" },
新用户{FirstName=“Jennifer”,MiddleName=“Wine”,LastName=“Long”,Email=“Jennifer。long@gmail.com"}
};
//对一个属性名有效
_用户=用户;
var user=GetByPropertyName(“FirstName”、“James”);
//对一个属性名有效
_用户=用户;
var user1=GetByPropertyName(“Email”,“james”。hall@hotmail.com");
//需要帮助吗
//对于GetByPropertyName,有两个或多个属性
var filters=newdictionary();
过滤器。添加(“名字”、“约翰”);
过滤。添加(“电子邮件”,“约翰”。long@gmail.com");
var user2=GetByPropertyNames(过滤器);
}
公共静态用户GetByPropertyName(对象propertyName,对象值)
{
var result=_users.AsQueryable().Where(propertyName.ToString(),value).FirstOrDefault();
返回结果;
}
公共静态用户GetByPropertyNames(字典过滤器)
{
var result=_users.AsQueryable().Where(filters.FirstOrDefault();
返回null;
}
}
公共类用户
{
公共字符串名{get;set;}
公共字符串MiddleName{get;set;}
公共字符串LastName{get;set;}
公共字符串电子邮件{get;set;}
}
}
Extensions.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
static List<User> _users = new List<User>();
static void Main(string[] args)
{
var users = new List<User> {
new User { FirstName = "John", MiddleName = "Hall", LastName = "Long", Email="john.long@gmail.com"},
new User { FirstName = "John", MiddleName = "Wine", LastName = "Crawford", Email="john.crawford@gmail.com" },
new User { FirstName = "James", MiddleName = "Cage", LastName = "Hall", Email="james.hall@hotmail.com" },
new User { FirstName = "Larry", MiddleName = "Wine", LastName = "Crawford", Email="larry.crawford@gmail.com" },
new User { FirstName = "Jennifer", MiddleName = "Wine", LastName = "Long", Email="jennifer.long@gmail.com"}
};
//works okay for one property name
_users = users;
var user = GetByPropertyName("FirstName", "James");
//works okay for one property name
_users = users;
var user1 = GetByPropertyName("Email", "james.hall@hotmail.com");
//NEED HELP
//For GetByPropertyNames two or more properties
var filters = new Dictionary<object, object>();
filters.Add("FirstName", "John");
filters.Add("Email", "john.long@gmail.com");
var user2 = GetByPropertyNames(filters);
}
public static User GetByPropertyName(object propertyName, object value)
{
var result = _users.AsQueryable().Where(propertyName.ToString(), value).FirstOrDefault();
return result;
}
public static User GetByPropertyNames(Dictionary<object, object> filters)
{
var result = _users.AsQueryable().Where(filters).FirstOrDefault();
return null;
}
}
public class User
{
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace ConsoleApplication1
{
public static class Extensions {
public static IQueryable<T> Where<T>(this IQueryable<T> source, string propertyName, object value) {
return (IQueryable<T>)Where((IQueryable)source, propertyName, value);
}
public static IQueryable Where(this IQueryable source, string propertyName, object value) {
var x = Expression.Parameter(source.ElementType, "x");
var selector = Expression.Lambda(
Expression.Equal(
Expression.PropertyOrField(x, propertyName),
Expression.Constant(value)
), x
);
return source.Provider.CreateQuery(
Expression.Call(typeof(Queryable), "Where", new Type[] { source.ElementType }, source.Expression, selector)
);
}
//NEED HELP
//TO DO
public static IQueryable<T> Where<T>(this IQueryable<T> source, Dictionary<object, object> filters)
{
return (IQueryable<T>)Where((IQueryable)source, filters);
}
public static IQueryable Where(this IQueryable source, Dictionary<object, object> filters)
{
var x = Expression.Parameter(source.ElementType, "x");
//NEED HELP
//expression for _users.FirstOrDefault(x=>x.Filter1==Filter1Value && x.Filter2==Filter2Value && so on and so fort depends on how many filters are passed as arguments);
//var selector = Expression.Lambda(
// Expression.Equal(
// Expression.PropertyOrField(x, propertyName),
// Expression.Constant(value)
// ), x
//);
//return source.Provider.CreateQuery(
// Expression.Call(typeof(Queryable), "Where", new Type[] { source.ElementType }, source.Expression, selector)
//);
//remove line below
return null;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Linq.Expressions;
运用系统反思;
命名空间控制台应用程序1
{
公共静态类扩展{
公共静态IQueryable Where(此IQueryable源、字符串属性名称、对象值){
返回(IQueryable),其中((IQueryable)来源、属性名称、值);
}
公共静态IQueryable Where(此IQueryable源、字符串属性名称、对象值){
var x=Expression.Parameter(source.ElementType,“x”);
var选择器=表达式.Lambda(
表达式。相等(
表达式.PropertyOrField(x,propertyName),
表达式.常量(值)
),x
);
返回source.Provider.CreateQuery(
调用(typeof(Queryable),“Where”,新类型[]{source.ElementType},source.Expression,选择器)
);
}
//需要帮助吗
//做
公共静态IQueryable Where(此IQueryable源,字典筛选器)
{
返回(IQueryable),其中((IQueryable)源,过滤器);
}
公共静态IQueryable Where(此IQueryable源,字典筛选器)
{
var x=Expression.Parameter(source.ElementType,“x”);
//需要帮助吗
//_users.FirstOrDefault的表达式(x=>x.Filter1==Filter1Value&&x.Filter2==Filter2Value&&依此类推,这取决于作为参数传递的过滤器数量);
//var选择器=表达式.Lambda(
//表达式。相等(
//表达式.PropertyOrField(x,propertyName),
//表达式.常量(值)
//),x
//);
//返回source.Provider.CreateQuery(
//调用(typeof(Queryable),“Where”,新类型[]{source.ElementType},source.Expression,选择器)
//);
//删除下面的行
返回null;
}
}
}
将您的IQueryable放到何处(此IQueryable源,字典过滤器)
并按如下方式更新您的通用版本:
public static IQueryable<T> Where<T>(this IQueryable<T> source, Dictionary<object, object> filters)
{
foreach (var kv in filters)
{
source = source.Where(kv.Key.ToString(), kv.Value);
}
return source;
}
公共静态IQueryable Where(此IQueryable源,字典过滤器)
{
foreach(滤波器中的var kv)
{
source=source.Where(kv.Key.ToString(),kv.Value);
}
返回源;
}
添加多个Where()语句意味着和逻辑。如果你想要的是逻辑,那会更痛苦。你的解决方案正是我所需要的!令人惊叹的!谢谢