[英]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.