Sql server 热巧克力GraphQL批处理查询并将选择和过滤中间件应用于EF SQL
使用热巧克力版本:10.5.5 并给出以下Sql server 热巧克力GraphQL批处理查询并将选择和过滤中间件应用于EF SQL,sql-server,graphql,entity-framework-core,hotchocolate,Sql Server,Graphql,Entity Framework Core,Hotchocolate,使用热巧克力版本:10.5.5 并给出以下客户域模型: public class Customer { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int CustomerID { get; set; } public string FirstName { get; set; } public string LastName { get; set; } pub
客户
域模型:
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;
生成以下两条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')
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')
使用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);
生成以下单个SQL语句:
SELECT [c].[FirstName], [c].[LastName]
FROM [SalesLT].[Customer] AS [c]
WHERE [c].[CompanyName] in (N'Front Sporting Goods', N'Front Sporting Goods')
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')
这种方法的缺点是,过滤
和选择
未被纳入EF生成的动态创建的SQL语句中,这仅在结果集从数据库返回后应用
如何在查询界面上返回一个
IQueryable
,以便过滤和选择中间件将应用并被分解到动态生成的SQL语句中,并且仍然强制在单个批处理中执行该语句?热巧克力的数据API和数据加载程序不起作用我们在一起很好。
这是两种不同的方法,不能在同一个解析器中混合使用
过滤在解析器级别工作,而数据加载程序在解析器执行之外运行
此查询包含两个解析程序:
query {
friendlyBikeShop: customers (where: { companyName: "Friendly Bike Shop"}){
firstName
lastName
}
frontSportingGoods: customers (where: { companyName: "Front Sporting Goods"}){
firstName
lastName
}
}
因此,您可以使用过滤和投影以及两个查询,也可以使用数据加载程序仅执行一个查询
作为替代查询,您还可以执行以下操作:
query {
customers (
where: {
companyName_in: [
"Friendly Bike Shop",
"Front Sporting Goods"
]
}){
firstName
lastName
}
}
这将在一个请求中返回两个结果