簡體   English   中英

LINQ從Queryable中選擇加入列表

[英]LINQ select from Queryable joining a List

我正在使用EF來連接使用列表的表。

我有出勤表:

Attendance
----------
UserBaseId
ClassroomID
Attendance Status ...etc

另外,我的內存中有一個出席者IEnumerable,結構相同,我們稱之為newAttendance。

我需要從出勤表​​中找到與newAttendance列表中的UserBaseId和ClassroomId匹配的所有記錄。

到目前為止,我已經嘗試過了

var entriesInAttendanceTable = context.Attendance.Where(
            x => (newAttendance .Select(i => i.UserBaseId).Contains(x.UserBaseId))
            && newAttendance .Select(i => i.ClassRoomId).Contains(x.ClassRoomId)
            ).ToList();

這將導致以下SQL查詢:

SELECT 
[Extent1].[Id] AS [Id], 

[Extent1].[ClassRoomId] AS [ClassRoomId], 

[Extent1].[UserBaseId] AS [UserBaseId], 
[Extent1].[CreatedOn] AS [CreatedOn], 
[Extent1].[UpdatedOn] AS [UpdatedOn], 
[Extent1].[UpdatedByUser_Id] AS [UpdatedByUser_Id], 
[Extent1].[CreatedByUser_Id] AS [CreatedByUser_Id]
FROM [dbo].[Attendance] AS [Extent1]
WHERE ( EXISTS (SELECT 
    1 AS [C1]
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable1]
    WHERE 1 = 0
)) AND ( EXISTS (SELECT 
    1 AS [C1]
    FROM  ( SELECT 1 AS X ) AS [SingleRowTable2]
    WHERE 1 = 0
))

還嘗試了加入,但沒有成功。

TIA

我相信這應該做您想要的:

var entriesInAttendanceTable = context.Attendance.Where(x => (newAttendance.Any(
    y => y.UserBaseId == x.UserBaseId && y.ClassRoomId == x.ClassRoomId)));

通常不支持此功能,因此您要么需要

(A)建立並執行UNION查詢,如下所示:

var entriesInAttendanceTable = newAttendance
    .Select(y => context.Attendance.Where(x => y.FirstName == x.FirstName && y.LastName == x.LastName))
    .Aggregate(Queryable.Union)
    .ToList();

(B)建立並執行基於OR的查詢,如下所示:

幫手:

public static class QueryableExtensions
{
    public static IQueryable<T> Match<T>(this IQueryable<T> source, IEnumerable<T> target, Expression<Func<T, T, bool>> by)
    {
        var parameter = by.Parameters[0];
        var condition = target
            .Select(item => by.Body.ReplaceParameter(by.Parameters[1], Expression.Constant(item)))
            .DefaultIfEmpty()
            .Aggregate(Expression.OrElse) ?? Expression.Constant(false);
        var predicate = Expression.Lambda<Func<T, bool>>(condition, parameter);
        return source.Where(predicate);
    }

    public static Expression ReplaceParameter(this Expression expression, ParameterExpression source, Expression target)
    {
        return new ParameterReplacer { Source = source, Target = target }.Visit(expression);
    }

    class ParameterReplacer : ExpressionVisitor
    {
        public ParameterExpression Source;
        public Expression Target;
        protected override Expression VisitParameter(ParameterExpression node)
        {
            return node == Source ? Target : base.VisitParameter(node);
        }
    }
}

用法:

var entriesInAttendanceTable = context.Attendance
    .Match(newAttendance, (x, y) => y.FirstName == x.FirstName && y.LastName == x.LastName)
    .ToList();

請注意,如果newAttendance列表很大,兩種解決方案都可能會出現問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM