我正在使用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
答案 0 :(得分:0)
我相信这应该做你想做的事情:
var entriesInAttendanceTable = context.Attendance.Where(x => (newAttendance.Any(
y => y.UserBaseId == x.UserBaseId && y.ClassRoomId == x.ClassRoomId)));
答案 1 :(得分: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
列表很大,则两种解决方案都可能会出现问题。