使用 HotChocolate 版本:10.5.5
并给出以下Customer
域模型:
public class Customer
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int CustomerID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string CompanyName { get; set; }
public string SalesPerson { get; set; }
}
Customers
在查询界面中公开实体框架数据库集时:
[UseSelection]
[UseFiltering]
public IQueryable<Customer> GetCustomers([Service] AdventureWorksContext ctx) => ctx.Customers;
并执行以下 graphql 查询:
query {
friendlyBikeShop: customers (where: { companyName: "Friendly Bike Shop"}){
firstName,
lastName
},
frontSportingGoods: customers (where: { companyName: "Front Sporting Goods"}){
firstName,
lastName
}
}
产生以下两条 SQL 语句:
SELECT [c].[FirstName], [c].[LastName]
FROM [SalesLT].[Customer] AS [c]
WHERE [c].[CompanyName] = N'Front Sporting Goods'
SELECT [c].[FirstName], [c].[LastName]
FROM [SalesLT].[Customer] AS [c]
WHERE [c].[CompanyName] = N'Front Sporting Goods'
这并不理想,因为我想将其合并到一个 SQL 语句中:
SELECT [c].[FirstName], [c].[LastName]
FROM [SalesLT].[Customer] AS [c]
WHERE [c].[CompanyName] in (N'Front Sporting Goods', N'Front Sporting Goods')
使用 a 解决此问题的第一次尝试GroupDataLoader
如下:
[UseSelection]
[UseFiltering]
public Task<Customer[]> GetCustomersByCompanyName(IResolverContext resolverCtx, [Service] AdventureWorksContext ctx, string companyName) =>
resolverCtx.GroupDataLoader<string, Customer>("customers", async keys =>
{
var customers = await ctx.Customers.Where(customer => keys.Any(key => key == customer.CompanyName)).ToListAsync();
return customers.ToLookup(customer => customer.CompanyName);
}).LoadAsync(companyName, default);
并执行以下graphql:
query {
friendlyBikeShop: customersByCompanyName(companyName: "Friendly Bike Shop"){
firstName,
lastName
},
frontSportingGoods: customersByCompanyName(companyName: "Front Sporting Goods"){
firstName,
lastName
}
}
生成以下单个 SQL 语句:
SELECT [c].[CustomerID], [c].[CompanyName], [c].[FirstName], [c].[LastName], [c].[SalesPerson]
FROM [SalesLT].[Customer] AS [c]
WHERE [c].[CompanyName] IN (N'Friendly Bike Shop', N'Front Sporting Goods')
这种方法的缺点是Filtering
并且Selection
没有考虑到由 EF 生成的动态创建的 SQL 语句中,这仅在结果集从数据库返回之后应用。
如何IQueryable
在查询接口上返回一个,以便中间件应用Filtering
并Selection
考虑到动态生成的 SQL 语句中,并且仍然强制它在单个批处理中执行?