2016-08-20 80 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列表大。