在linq where子句中使用方法返回值

时间:2020-07-07 09:49:40

标签: c# sql linq methods lambda

在这里,我有一个linq查询,它工作正常,但我试图使其更具可读性。基本上,我将新的DateTime范围添加到数据库中,但是它不能与现有的范围相交。我试图编写一种方法,传递开始时间和结束时间,并在where子句中使用返回值,但是据我所知,不能在查询中使用函数。有什么建议吗?

var salariesInPeriod = await db.Salaries
                .Where(x => x.Id != salaryIdToIgnore)
                .Where(x => x.UserId == userId)
                .Where(x =>
                    //These filters check if there are any overlapping ends
                (x.StartDate <= startDate &&
                 startDate <= (x.EndDate ?? DateTime.MaxValue))
                ||
                (x.StartDate <= (endDate ?? DateTime.MaxValue) &&
                 (endDate ?? DateTime.MaxValue) <= (x.EndDate ?? DateTime.MaxValue))
                ||
                (startDate <= x.StartDate &&
                 x.StartDate <= (endDate ?? DateTime.MaxValue))
                ||
                (startDate <= (x.EndDate ?? DateTime.MaxValue) &&
                 (x.EndDate ?? DateTime.MaxValue) <= (endDate ?? DateTime.MaxValue))
                )

                .Select(x => new
                {
                    x.StartDate,
                    x.EndDate
                })
                .ToListAsync();

这就是我尝试过的:

public bool CheckIntersections(DateTime currentStart, DateTime newStart, DateTime? currentEnd, DateTime? newEnd)
    {
        if ((currentStart <= newStart &&
             newStart <= (currentEnd ?? DateTime.MaxValue))
            ||
            (currentStart <= (newEnd ?? DateTime.MaxValue) &&
             (newEnd ?? DateTime.MaxValue) <= (currentEnd ?? DateTime.MaxValue))
            ||
            (newStart <= currentStart &&
             currentStart <= (newEnd ?? DateTime.MaxValue))
            ||
            (newStart <= (currentEnd ?? DateTime.MaxValue) &&
             (currentEnd ?? DateTime.MaxValue) <= (newEnd ?? DateTime.MaxValue)))
        {
            return true;
        }

        return false;
    }

然后我尝试在查询中使用结果:

var salariesInPeriod = await db.Salaries
            .Where(x => x.Id != salaryIdToIgnore)
            .Where(x => x.UserId == userId)
            .Where(x => CheckIntersections(x.StartDate, startDate, x.EndDate,endDate) == true)

            .Select(x => new
            {
                x.StartDate,
                x.EndDate
            })
            .ToListAsync();

有什么想法可以简化该查询吗?

1 个答案:

答案 0 :(得分:1)

您不能在linq查询中使用任何功能。为了提高可读性,您可以使用扩展方法:

public static class SalaryQueryExtensions
{
    public static IQueryable<Salary> WithIntersections(
        this IQueryable<Salary> salaries, DateTime currentStart, DateTime newStart, DateTime? currentEnd, DateTime? newEnd)
    {
        // return your query. Example:
        // salaries.Where(x=> x.DateTime > currentStart);
    }

    public static IQueryable<Salary> WithIgnoreId(this IQueryable<Salary> salaries, Guid id)
    {
        // return your query.
    }

    public static IQueryable<Salary> WithUserID(this IQueryable<Salary> salaries, Guid userId)
    {
        // return your query.
    }
}

然后使用如下扩展方法:

var salariesInPeriod = await db.Salaries
            .WithIgnoreId(salaryIdToIgnore)
            .WithUserId(userId)
            .WithIntersections(startDate,endDate)
            .ToListAsync();
相关问题