【发布时间】:2020-12-01 17:15:31
【问题描述】:
使用 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 dbset 时:
[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')
使用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 语句中,并且仍然强制它在单个中执行批量?
【问题讨论】:
标签: sql-server graphql entity-framework-core hotchocolate