我终于找到了一个解决方案:) 因为 linq 的 Where 方法接受Func<T,bool>
了,所以我编写了一个返回 a 的函数,Func<T,bool>
并在我的 Where 中调用它,如下所示:
db.Kiosks
.Where(QueryCurrentKioskDesignation(db, d => d.Type.DefinitionId == id))
此函数获取一个 Func 作为谓词,以根据其当前的指定数据过滤我们的信息亭。这是 QueryCurrentKioskDesignation 函数:
public static Func<Kiosk, bool> QueryCurrentKioskDesignation(DataContext db,
Func<KioskDesignation, bool> predicate)
{
return k => db.KioskDesignations.Where(q => q.Kiosk.KioskId == k.KioskId &&
(!q.RedesignedAt.HasValue ||
q.RedesignedAt.Value <= DateTime.Now))
.OrderByDescending(q => q.RedesignedAt)
.Take(1).Any(predicate);
}
更新:
我注意到 Linq 方法IEnumerable<T>
在我们使用时返回一个Func<>
(这意味着 Linq 立即调用函数并返回一个 IEnumerable)但最好使用表达式让 Linq 构建一个表达式树,我们可以稍后执行它。为了实现这一点,我只是更改了我的 QueryCurrentKioskDesignation 签名以接受一个表达式并返回一个:
public static Expression<Func<Kiosk, bool>> QueryCurrentKioskDesignation(DataContext db,
Expression<Func<KioskDesignation, bool>> predicate)
现在我可以使用 IQueryalbe 并通过对数据库的单个查询来获取我想要的所有数据并向您展示它的美丽这里是我使用 EFProf 生成的查询
SELECT TOP (20) [Extent1].[KioskId] AS [KioskId],
[Extent1].[Code] AS [Code],
[Extent1].[Barcode] AS [Barcode],
[Extent1].[Notes] AS [Notes],
[Extent1].[CheckedAt] AS [CheckedAt],
[Extent1].[SearchKeywords] AS [SearchKeywords],
[Extent1].[CreatedAt] AS [CreatedAt],
[Extent1].[CreatedBy] AS [CreatedBy],
[Extent1].[LastEditAt] AS [LastEditAt],
[Extent1].[LastEditBy] AS [LastEditBy],
[Extent1].[Guild_KioskGuildId] AS [Guild_KioskGuildId]
FROM [dbo].[Kiosks] AS [Extent1]
WHERE (EXISTS (SELECT 1 AS [C1]
FROM (SELECT TOP (1) [Project1].[Activity_DefinitionId] AS [Activity_DefinitionId]
FROM (SELECT [Extent2].[RedesignedAt] AS [RedesignedAt],
[Extent2].[Activity_DefinitionId] AS [Activity_DefinitionId]
FROM [dbo].[KioskDesignations] AS [Extent2]
WHERE ([Extent2].[Kiosk_KioskId] = [Extent1].[KioskId])
AND (([Extent2].[RedesignedAt] IS NULL)
OR ([Extent2].[RedesignedAt] <= (SysDateTime())))) AS [Project1]
ORDER BY [Project1].[RedesignedAt] DESC) AS [Limit1]
WHERE (CASE
WHEN (0 /* @p__linq__0 */ = 1) THEN
CASE
WHEN (14 = [Limit1].[Activity_DefinitionId]) THEN cast(1 as bit)
WHEN (14 <> [Limit1].[Activity_DefinitionId]) THEN cast(0 as bit)
END
WHEN (14 <> [Limit1].[Activity_DefinitionId]) THEN cast(1 as bit)
WHEN (14 = [Limit1].[Activity_DefinitionId]) THEN cast(0 as bit)
END) = 1))
AND (EXISTS (SELECT 1 AS [C1]
FROM (SELECT TOP (1) [Project3].[Type_DefinitionId] AS [Type_DefinitionId]
FROM (SELECT [Extent3].[RedesignedAt] AS [RedesignedAt],
[Extent3].[Type_DefinitionId] AS [Type_DefinitionId]
FROM [dbo].[KioskDesignations] AS [Extent3]
WHERE ([Extent3].[Kiosk_KioskId] = [Extent1].[KioskId])
AND (([Extent3].[RedesignedAt] IS NULL)
OR ([Extent3].[RedesignedAt] <= (SysDateTime())))) AS [Project3]
ORDER BY [Project3].[RedesignedAt] DESC) AS [Limit2]
WHERE [Limit2].[Type_DefinitionId] = 4 /* @p__linq__1 */))
这就是我喜欢 Linq 的原因 :)