0

我有这个程序,我扩展了 LINQ 表达式以使用任何属性名称和值作为参数来获取结果。我的扩展仅适用于一个属性,但是我需要查找并将两个或多个属性作为过滤器传递。谁能帮我扩展我的 LINQ?下面是我的代码实现。我使用了控制台应用程序。

基于我刚刚调用的用户列表的示例代码

GetByPropertyName("PropertyName", "Value");

例如

var user = GetByPropertyName("FirstName", "James");

程序.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; }
    }
}

扩展.cs

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

    }
}
4

1 回答 1

1

删除您的IQueryable Where(this IQueryable source, Dictionary<object, object> filters)并更新您的通用版本,如下所示:

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

添加多个 Where() 语句意味着 AND 逻辑。如果您想要 OR 逻辑,那将更加痛苦。

于 2013-09-05T03:22:05.097 回答