2016-08-20 2 views
0

Я использую EF для присоединения к таблице с использованием списка.LINQ select from Queryable, соединяющий список

У меня есть посещаемость таблицы:

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

Кроме того, у меня есть посещаемость IEnumerable в памяти, одной и той же структуры, давайте назовем его newAttendance.

Мне нужно найти все записи из таблицы посещаемости, которая соответствует UserBaseId и ClassroomId в newAttendance List.

до сих пор я попытался это,

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 
)) 

также попытался присоединиться, но он не работал.

ТИА

+0

Что происходит, когда вы вызываете .ToList(), чтобы выполнить запрос в этом месте? Кроме того, вы должны выбрать идентификаторы в памяти, а не внутри запроса. – 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 список большой.

Смежные вопросы