Sql server 热巧克力GraphQL批处理查询并将选择和过滤中间件应用于EF SQL

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

使用热巧克力版本: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; }
    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
  }
}
这将在一个请求中返回两个结果