【问题标题】:Getting all Data from SQL using LINQ with comma-separated IDs使用带有逗号分隔 ID 的 LINQ 从 SQL 获取所有数据
【发布时间】:2020-07-28 06:15:46
【问题描述】:

我确实有一串用逗号分隔的 Empid,例如:

EMpID:"2007,2008,2002,1992,1000,2108,1085

我需要使用 LINQ 查询检索所有指定员工的记录。 我尝试了循环,但我需要以高效和更快的方式实现它。

这是我使用循环所做的。

string[] EMpID_str = LeaveDictionary["EMpID"].ToString().Split(',');

for (int i = 0; i < EMpID_str.Length; i++)
            {
                EMpID = Convert.ToInt32(EMpID_str[i]);

               //Linq to get data for each Empid goes here
             }

但我需要的是使用单个 LINQ 或 Lambda 查询来检索相同的内容。不循环

【问题讨论】:

  • 到目前为止你尝试过什么?显示一些您已经拥有的示例代码 - 这有助于简化网站的其他成员以便快速回答您。
  • 首先将您的,(逗号)分隔的empId转换为字符串数组,如var empArr = EmpId.split(',');var employeesResult = emplyeeList.Where(x =&gt; empArr.contains(x.EmpId.ToString()));
  • @Rafalon 是的,你能提供更多关于相同的细节吗?
  • @Rajeev 数组没有 contains
  • @MichaelSchönbauer 是不是有一个用于数组的 Linq 扩展,它允许我们使用 Contains 呢?接受的解决方案here 似乎在数组上使用Contains

标签: c# asp.net linq lambda webapi


【解决方案1】:

首先将您的,(逗号)分隔的 empId 转换为字符串数组,如下所示:

var empArr = EmpId.split(','); 
var employeesResult = emplyeeList.Where(x => empArr.contains(x.EmpId.ToString()));

希望对大家有所帮助。

【讨论】:

    【解决方案2】:

    如果您要获取的 Id 是数字,而不是字符串,那么您不应该将字符串转换为字符串数组,而是转换为数字序列:

    IEnumerable<int> employeeIdsToFetch = LeaveDictionary["EMpID"].ToString()
        .Split(',')
        .Select(splitText => Int32.Parse(splitText));
    

    获取所有具有这些 ID 的员工:

    var fetchedEmployees = dbContext.Employees
        .Where(employee => employeeIdsToFetch.Contains(employee.Id))
        .Select(employee => new
        {
             // Select only the employee properties that you plan to use:
             Id = employee.Id,
             Name = employee.Name,
             ...
        });
    

    【讨论】:

    • 感谢@Harald 的帮助和建议。
    【解决方案3】:

    您可以使用Expression 类从您的字符串构建一个Func&lt;int, bool&gt; 并将其与Where 方法一起使用:

    var str = "2,5,8,9,4,6,7";
    
    var para = Expression.Parameter(typeof(int));
    
    var body = str.Split(",")
        .Select(s => int.Parse(s))
        .Select(i => Expression.Constant(i))
        .Select(c => Expression.Equal(para, c))
        .Aggregate((a, b) => Expression.Or(a, b));
    
    Func<int, bool> func = Expression.Lambda<Func<int, bool>>(body, para).Compile();
    

    如果您使用 linq to SQL 的这个解决方案只是不要在最后编译表达式,而是让 linq to SQL 引擎将其编译为有效的 SQL 表达式。

    代替Aggregate 方法(将产生具有线性复杂度的表达式),可以使用分而治之的方法将值折叠成一个值。

    以此类为例:

    public static class Helper
    {
        public static T EfficientFold<T>(this List<T> list, Func<T, T, T> func)
        {
            return EfficientFold(list, 0, list.Count, func);
        }
    
        private static T EfficientFold<T>(List<T> list, int lowerbound, int upperbound, Func<T, T, T> func)
        {
            int diff = upperbound - lowerbound;
            var mid = lowerbound + diff / 2;
    
            if (diff < 1)
            {
                throw new Exception();
            }
            else if (diff == 1)
            {
                return list[lowerbound];
            }
            else
            {
                var left = EfficientFold(list, lowerbound, mid, func);
                var right = EfficientFold(list, mid, upperbound, func);
    
                return func(left, right);
            }
        }
    }
    

    然后我们可以做

    var body = str.Split(",")
        .Select(s => int.Parse(s))
        .Select(i => Expression.Constant(i))
        .Select(c => Expression.Equal(para, c))
        .ToList()
        .EfficientFold((a, b) => Expression.Or(a, b));
    

    这使评估的复杂性为log(n)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-22
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多