2016-08-20 79 views
0

我正在使用EF使用列表来加入表。LINQ从Queryable加入列表中选择

我有考勤表:

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

+0

当你调用.ToList(),在这个地方实际执行查询时会发生什么?此外,您应该选择内存中的ID,而不是在查询内。 – DevilSuichiro

+0

不会选择任何内容,尽管我的条目与条件匹配。更新后的问题与SQL查询 – SJMan

+0

“var x in y”语法是什么意思?我以前从来没有见过。 – smead

回答

0

我相信这应该做你想要什么:

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

一般来说,这是不支持的,所以你要么需要

(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列表大。