【问题标题】:Include not working with join entities包括不使用连接实体
【发布时间】:2016-11-02 13:01:13
【问题描述】:

例如,我有以下实体(多对多,我还删除了不必要的道具):

public class Buffet
{
    public int Id {get; set;}
    public string Name {get; set;}
}

public class Recipe
{
    public int Id {get; set;}
    public string Name {get; set;}
    public int CategoryId {get; set;}
    public virtual Category Category {get; set;}
}

public class Category
{
    public int Id {get; set;}
    public string Name {get; set;}
}

加入实体:

public class BuffetRecipe
{
    public int BuffetId {get; set;}
    public virtual Buffet Buffet {get; set;}
    public int RecipeId {get; set;}
    public virtual Recipe Recipe {get; set;}
}

我想获取属于特定自助餐的所有食谱并希望包含食谱类别。

public IList<Recipe> GetRecipes(int buffetId)
{
    return _dbContext.BuffetRecipes
    .Where(item => item.BuffetId == buffetId)
    .Include(item => item.Recipe)
    .ThenInclude(item => item.Category)
    .Select(item => item.Recipe)
    .ToList();
}

我得到的列表总是返回带有 prop Category = null 的食谱。 我没有找到使 Include() 与 Select() 一起工作的解决方案...

我做错了什么??

更新:

我可以让它这样工作......但我感觉这不是一个好方法,因为我有 2 个 ToList() 调用......但现在我的结果中包含了类别:

public IList<Recipe> GetRecipes(int buffetId)
{
    return _dbContext.BuffetRecipes
    .Where(item => item.BuffetId == buffetId)
    .Include(item => item.Recipe)
    .ThenInclude(item => item.Category)
    .ToList()
    .Select(item => item.Recipe)
    .ToList();
}

【问题讨论】:

  • 你为什么要使用BuffetRecipe 类而不是BuffetRecipe 上的集合?你失去了在两者之间旅行的能力。您的 BuffetRecipe 类将被创建为您不需要在 C# 中管理多对多关系的表。
  • 在 EF 核心中,没有连接实体就没有多对多...所以我必须手动创建一个 BuffetRecipe 实体以使这种关系在新的 EF 核心中工作...
  • 我只想补充一点,包含在没有 Select 的情况下工作。这是设计使然吗?
  • Include 仅在您不返回投影.Select(item =&gt; item.Recipe) 时才有效。您应该以_dbContext.Recipes 开始查询。
  • 好的,感谢您提供的信息...您能帮我实现我想要的 linq 查询吗?

标签: entity-framework asp.net-core entity-framework-core .net-core


【解决方案1】:

Include只有在可以应用于查询的最终结果时才有效。

可以把它改成...

return _dbContext.BuffetRecipes
    .Where(item => item.BuffetId == buffetId)
    .Select(item => item.Recipe)
    .Include(rcp => rcp.Category)
    .ToList()

...但是这样做的缺点是您复制了Recipes(与BuffetRecipes一样多)。最好以Recipe开始查询:

return _dbContext.Recipes
    .Where(rcp => rcp.BuffetRecipes.Any(br => br.BuffetId == buffetId))
    .Include(rcp => rcp.Category)
    .ToList();

你看我冒昧地添加了一个导航属性Recipe.BuffetRecipes。这对您的模型应该没有任何问题(相反,我会说)。

【讨论】:

  • 感谢您的反馈...但我必须告诉您,您的第一个查询不起作用...意味着它不包含类别...即使我将包含放在 Select 之后()。
  • 您的第二个查询结果如下 SQL:SELECT xxxxxxxxxx FROM [Recipes] AS [item] INNER JOIN [RecipeCategories] AS [r] ON [item].[CategoryId] = [r].[Id ] WHERE EXISTS ( SELECT 1 FROM [BuffetRecipes] AS [br] WHERE ([br].[BuffetId] = @__buffetId_0) AND ([item].[Id] = [br].[RecipeId])) 看起来不太对我很好:-(
  • 这是我所期望的查询。至于第一个查询,不幸的是,您永远无法了解 EF 核心的工作原理,但正如我所说,我仍然不喜欢该查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-02
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
相关资源
最近更新 更多