Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用GraphQL.EntityFramework公开多对多关系_C#_Entity Framework_Graphql - Fatal编程技术网

C# 使用GraphQL.EntityFramework公开多对多关系

C# 使用GraphQL.EntityFramework公开多对多关系,c#,entity-framework,graphql,C#,Entity Framework,Graphql,我有一个相当直接的.NET Core EF模型,由一个SQL Server数据库支持,我正在通过.NET Core Web API中的GraphQL公开该模型,并使用该模型构建 我有一些多对多的关系,比如: 为清晰起见,实体模型已删除此表单中的不相关位: public class StoreEntity { [Key] public int StoreId { get; set; } public string Name { get; set; } // etc

我有一个相当直接的.NET Core EF模型,由一个SQL Server数据库支持,我正在通过.NET Core Web API中的GraphQL公开该模型,并使用该模型构建

我有一些多对多的关系,比如:

为清晰起见,实体模型已删除此表单中的不相关位:

public class StoreEntity
{
    [Key]
    public int StoreId { get; set; }
    public string Name { get; set; }

    // etc...

    public List<StoreCategoryEntity> Categories { get; set; }
}

public class StoreCategoryEntity
{
    [Required]
    public int StoreId { get; set; }
    [Required]
    public int CategoryId { get; set; }

    public CategoryEntity Category { get; set; }
}

public class CategoryEntity
{
    [Key]
    public int CategoryId { get; set; }
    public string Name { get; set; }
}
使用GraphQL.EntityFramework,典型的对象图类型如下:这是构造函数:

public StoreType(IEfGraphQLService<MyDbContext> efGraphQlService) : base(efGraphQlService)
{
    Field(x => x.StoreId).Description("The store ID");
    Field(x => x.Name).Description("The store name");

    // ...

    AddNavigationListField(
        name: "categories",
        resolve: context => context.Source.Categories);
}
这很好,但比我希望的要复杂一些。我希望导航列表字段的类型为Category,而不是StoreCategory。我试过这个:

public StoreType(IEfGraphQLService<MyDbContext> efGraphQlService) : base(efGraphQlService)
{
    Field(x => x.StoreId).Description("The store ID");
    Field(x => x.Name).Description("The store name");

    AddNavigationListField(
        name: "categories",
        resolve: context => context.Source.Categories.Select(x => x.Category));
}
…但此代码将为每个存储创建单独的DB往返,这正是GraphQL.EntityFramework设计用来避免的那种情况。

此功能:

public StoreType(IEfGraphQLService<MyDbContext> efGraphQlService) : base(efGraphQlService)
{
    Field(x => x.StoreId).Description("The store ID");
    Field(x => x.Name).Description("The store name");

    // ...

    AddNavigationListField(
        name: "categories",
        resolve: context => context.Source.Categories.Select(x => x.Category),
        includeNames: new[] { "Categories.Category" })
        .Description = "The categories for the store";

}
诀窍是对include使用点格式,它允许您定义include路径

之所以需要这样做,是因为GraphQL.EntityFramework将应用includeNames参数数组中的所有Include,但它们都应用于源实体级别:Store-不直接支持.ThenClude

Categories.Categories相当于.Includex=>x.Categories.thenCludex=>x.Categories

public StoreType(IEfGraphQLService<MyDbContext> efGraphQlService) : base(efGraphQlService)
{
    Field(x => x.StoreId).Description("The store ID");
    Field(x => x.Name).Description("The store name");

    AddNavigationListField(
        name: "categories",
        resolve: context => context.Source.Categories.Select(x => x.Category));
}
Field<ListGraphType<CategoryType>>(
    name: "categories",
    resolve: context =>
    {
        var dbContext = ResolveDbContext(context);
        return dbContext.StoreCategories
            .AsNoTracking()
            .Include(x => x.Category)
            .Where(x => x.StoreId == context.Source.StoreId)
            .Select(x => x.Category);
    });
public StoreType(IEfGraphQLService<MyDbContext> efGraphQlService) : base(efGraphQlService)
{
    Field(x => x.StoreId).Description("The store ID");
    Field(x => x.Name).Description("The store name");

    // ...

    AddNavigationListField(
        name: "categories",
        resolve: context => context.Source.Categories.Select(x => x.Category),
        includeNames: new[] { "Categories.Category" })
        .Description = "The categories for the store";

}