使用带有逗号分隔 ID 的 LINQ 从 SQL 获取所有数据

Getting all Data from SQL using LINQ with comma-separated IDs

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

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 查询来检索 same.Without 循环

如果您要获取的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,
         ...
    });

您可以使用 Expression class 从字符串构建 Func<int, bool> 并将其与 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 方法(这将产生具有线性复杂性的表达式)。

例如 class:

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)

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

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

希望对某人有所帮助。