【问题标题】:LINQ Query with Array input and variable Where Statements - Advice带有数组输入和变量 Where 语句的 LINQ 查询 - 建议
【发布时间】:2010-07-16 05:15:29
【问题描述】:

我想通过 WCF 数据服务使用 Silverlight 客户端 API 查询给定数组的数据。基本上,我想查询给定状态列表(数组)的员工。

我在想这样的事情:

public IQueryable<Employee> Load(string[] states)
{
     foreach (var x in states)
     {
           // LINQ query here with 1 to N .Where statements
           return from e in Context.Employees
           .Where(...)
     }
} 

假设我的数组中有 2 个项目,即我想按 2 个状态进行查询,我会手动执行以下操作:

return from e in Context.Employees
    .Where(e => e.State== states[0] || e.State == states[1])));

任何建议将不胜感激!

【问题讨论】:

  • 您使用的是 LINQ to SQL 还是实体框架或普通 LINQ?
  • 已编辑原始帖子 - 使用 WCF 数据服务 (Astoria 1.0) 和 Silverlight 3.0(Silverlight 客户端库)。

标签: c# linq


【解决方案1】:

您可以为条件动态构建表达式树。

var parameter = Expression.Parameter(typeof(Employee), "employee");

Expression condition = Expression.Constant(false);

foreach (var state in states)
{
    condition = Expression.OrElse(
        condition,
        Expression.Equal(
            Expression.Property(parameter, "State"),
            Expression.Constant(state)));
}

var expression = Expression.Lambda<Func<Employee, Boolean>>(condition, parameter);

然后执行调用。

var result = Context.Employees.Where(expression);

我不能 100% 确定这是否适合您,但我希望总体思路有所帮助。

【讨论】:

  • 可能不是Or,而是OrElse。还有Parameter(typeof(Employee)...
  • 谢谢,你是对的 - 我使用 String 的列表编写代码进行测试,忘记将其更改为 EmployeeOrOrElse 之间的区别应该无关紧要,但当然通常会使用条件 or 而不是正常的 or。
  • 好评@DanielBrückner 但 Equal 方法进行区分大小写的比较,而不是如何执行不区分大小写的比较? Expression.Contains() 方法不存在。
【解决方案2】:

Context.Employees.ToList().Where(x => states.Contains(x.State))

【讨论】:

  • 这不适用于 EntityFramework 或 LINQ to SQL。如果使用它,我假设是一个,因为参数是IQeryable 而不是IEnumerable
  • 如果你在 where 之前调用 tolist() 应该可以。
  • 如果这是一个大表,您可能需要考虑性能,因为所有员工都会被读入,然后应用过滤器
  • 他将不得不对其进行测试,但我很确定 EF 和 L2S 都不能将像列表这样的复杂对象转换为匹配的 SQL 语句——至少在 .NET 4.0 之前是这样。跨度>
  • 你的权利(我认为),但 tolist 将其转换为普通的列表对象,所以即使 ef 或 l2s 不支持它,你也应该在那时处理 L2o。运行过滤器时,查询已在数据库上执行。我会先测试它而不先使用 tolist,因为如果它有效的话,效率会更高。
【解决方案3】:

我认为这是一个可运行的示例,可以满足您的需求?给定一个州列表,它将为您提供这些州的员工。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> states = new List<string>();
            states.Add("SC");
            states.Add("TX");
            states.Add("NC");

            List<Employee> emps = new List<Employee>();
            emps.Add(new Employee() { State = "GA", Name = "Bill" });
            emps.Add(new Employee() { State = "TX", Name = "John" });
            emps.Add(new Employee() { State = "SC", Name = "Mary" });

            //Here's where the work is done.  The rest is fluff...
            var empsinstates = from e in emps where states.Contains(e.State) select e;

            foreach (var e in empsinstates)
            {
                Console.WriteLine(e.Name + " " + e.State);
            }
            Console.Read();
        }
    }
    class Employee
    {
        public string State;
        public string Name;
    }
}

【讨论】:

  • 这适用于 LINQ to Object,但(很肯定)不适用于 Entity Framework 或 LINQ to SQL。
  • 这是我得到的:{将 Linq 表达式转换为 URI 时出错:不支持“包含”方法。}
猜你喜欢
  • 1970-01-01
  • 2016-02-05
  • 1970-01-01
  • 1970-01-01
  • 2014-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多