C# “LINQ再利用”;其中;对特定类型进行筛选

C# “LINQ再利用”;其中;对特定类型进行筛选,c#,linq,azure-cosmosdb,C#,Linq,Azure Cosmosdb,我正在做一项任务,需要在LINQ语句的where子句中重用一个过滤器方法 下面是数据的结构(如NoSQL数据库) 下面是我从客户集合中获取筛选结果的方法 public static IQueryable<Customer> customersWhere(IQueryable<Customer> customerWhere, string customerType) { if (!string.IsNullOrEmpty(customerType))

我正在做一项任务,需要在LINQ语句的where子句中重用一个过滤器方法

下面是数据的结构(如NoSQL数据库)

下面是我从客户集合中获取筛选结果的方法

public static IQueryable<Customer> customersWhere(IQueryable<Customer> customerWhere, string customerType)
{
    if (!string.IsNullOrEmpty(customerType))
        customerWhere = customerWhere.Where(c => c.type == customerType);

    return customerWhere;

}
//customer filter
string customerType = "Type1";

var customersResult = customers.Select(c => c).AsQueryable();

//filtered result for customer
customersResult = customersWhere(customersResult, customerType);
通过上面的语句,我得到了结果(名为1和名为2的客户)

当我处理comments集合时,如果我想按客户类型过滤评论,我想在comment.customer对象上重用“customerWhere”方法。下面是我如何尝试重用此方法的

//pull customer comment. 
var commentsResult = comments.Select(c => c).AsQueryable();

//filtered comments by customer type
//I'd like to reuse my customersWhere method here.
commentsResult = commentsResult.Where(c => c.customer == 
customersWhere((IQueryable<Customer>)c.customer, customerType));
//获取客户评论。
var commentsResult=comments.Select(c=>c.AsQueryable();
//按客户类型筛选的评论
//我想在这里重用customersWhere方法。
commentsResult=commentsResult.Where(c=>c.customer==
customerwhere((IQueryable)c.customer,customerType));
我希望在结果中得到MyComment2和MyComment3。但我不断得到“无法将类型为“Customer”的对象强制转换为类型为“System.Linq.IQueryable`1[ConsoleApp1.Program+Customer]”


我如何才能在任何具有customer对象的集合上重复使用filter方法。

在这一行中,您试图将
customer
(我相信
Comment
只有一个
customer
)转换为
IQueryable

使用方法:

const string customerType = "Type1";
var comments = new Comment[]
    {
        new Comment(),
        new Comment(),
        new Comment {Customer = new Customer()}
    }.AsQueryable();

var customersResult = comments.Select(c => c.Customer).AsQueryable();
customersResult = CustomersWhere(customersResult, customerType);

var commentsResult = comments.Select(c => c).AsQueryable();
commentsResult = commentsResult.Where(c => CustomerWhere( c.Customer, customerType ));

您在
customersResult
中已经有了结果,您需要重新使用它,而不是再次调用该方法:

commentsResult = commentsResult.Where(c1 => customersResult.Any(c2 => c.customer == c2));
最好将“customersWhere()”方法设置为泛型,以便您可以在任何情况下使用它。将表达式作为参数而不是customerType传递。在这里使用委托

    public static IQueryable<T> customersWhere<T>(IQueryable<T> 
    customerWhere, 
    Expression<Func<T, bool>> predicate)
    {
       customerWhere = customerWhere.Where(predicate);
        return customerWhere;
    }

    static void Main(string[] args)
    {

        List<Customer> customers = new List<Customer>()
       {
           new Customer(){name="Name1", type ="Type1"},
           new Customer(){name="Name2", type ="Type2"},
           new Customer(){name="Name2", type ="Type1"}
       };

        List<CustomerWithComment> customerWithComment = new List<CustomerWithComment>()
       {
           new CustomerWithComment(){comment = "Customer1", customer = new Customer(){name="Name2", type ="Type2"}},
           new CustomerWithComment(){comment = "Customer2", customer = new Customer(){name="Name1", type ="Type1"}},
           new CustomerWithComment(){comment = "Customer3", customer = new Customer(){name="Name1", type ="Type1"}}
       };

        string customerType = "Type1";

        Expression<Func<Customer, bool>> predicate = i => i.type ==customerType;
        var listcustomer = customers.Select(c => c).AsQueryable();
        listcustomer = customersWhere<Customer>(listcustomer, predicate);

        Expression<Func<CustomerWithComment, bool>> customerWithCommentExpression = i => i.customer.type ==customerType;
        var commentsResult = customerWithComment.Select(c => c).AsQueryable();
        commentsResult = customersWhere<CustomerWithComment>(commentsResult, customerWithCommentExpression);

        Console.Read();
    }

正如我测试的那样,它工作得很好。希望它能对您有所帮助,如果您想更好地重用该方法以使其具有通用性,您将获得预期的输出

const string customerType = "Type1";
var comments = new Comment[]
    {
        new Comment(),
        new Comment(),
        new Comment {Customer = new Customer()}
    }.AsQueryable();

var customersResult = comments.Select(c => c.Customer).AsQueryable();
customersResult = CustomersWhere(customersResult, customerType);

var commentsResult = comments.Select(c => c).AsQueryable();
commentsResult = commentsResult.Where(c => CustomerWhere( c.Customer, customerType ));
commentsResult = commentsResult.Where(c1 => customersResult.Any(c2 => c.customer == c2));
    public static IQueryable<T> customersWhere<T>(IQueryable<T> 
    customerWhere, 
    Expression<Func<T, bool>> predicate)
    {
       customerWhere = customerWhere.Where(predicate);
        return customerWhere;
    }

    static void Main(string[] args)
    {

        List<Customer> customers = new List<Customer>()
       {
           new Customer(){name="Name1", type ="Type1"},
           new Customer(){name="Name2", type ="Type2"},
           new Customer(){name="Name2", type ="Type1"}
       };

        List<CustomerWithComment> customerWithComment = new List<CustomerWithComment>()
       {
           new CustomerWithComment(){comment = "Customer1", customer = new Customer(){name="Name2", type ="Type2"}},
           new CustomerWithComment(){comment = "Customer2", customer = new Customer(){name="Name1", type ="Type1"}},
           new CustomerWithComment(){comment = "Customer3", customer = new Customer(){name="Name1", type ="Type1"}}
       };

        string customerType = "Type1";

        Expression<Func<Customer, bool>> predicate = i => i.type ==customerType;
        var listcustomer = customers.Select(c => c).AsQueryable();
        listcustomer = customersWhere<Customer>(listcustomer, predicate);

        Expression<Func<CustomerWithComment, bool>> customerWithCommentExpression = i => i.customer.type ==customerType;
        var commentsResult = customerWithComment.Select(c => c).AsQueryable();
        commentsResult = customersWhere<CustomerWithComment>(commentsResult, customerWithCommentExpression);

        Console.Read();
    }
    public class Customer
    {
        public string name { get; set; }
        public string type { get; set; }
    }

    public class CustomerWithComment
    {
        public string comment { get; set; }
        public Customer customer { get; set; }
    }