【问题标题】:Entity Framework with Include and Select together包含和选择一起的实体框架
【发布时间】:2015-09-26 07:03:32
【问题描述】:

我有以下实体(伪代码以节省空间)

Program [ int Id, 
          string Name, 
          List<ProgramFoodType> ProgramFoodTypes, 
          List<ProgramFood> ProgramFoods]

ProgramFoodType[ int Id, int ProgramId, int Type, bool IsActive]
ProgramFood [ int Id, int ProgramId, Food Food, FoodType FoodType]
Food [int Id, string Name]
FoodType [int Id, string Name]

我的任务是获取单个 Program 及其相关 ProgramFoodTypes 条件 ProgramFoodType 应该是活动的,ProgramFoods 与相关实体 FoodFoodType

到目前为止,我使用了以下内容

1- 下面的查询将检索ProgramFoodTypesProgramFoods 的详细信息,但它会带来所有活动和非活动ProgramFoodTypes

var program = mEntities.Programs
                          .Include(p =>p.ProgramFoodTypes)
                          .Include(p =>p.ProgramFoods.Select(f =>f.Food))
                          .InClude(p =>p.ProgramFoods.Select( f =>f.FoodType))
                          .Where(m =>m.Id== Id);

2- 以下查询将检索详细信息,但缺少 FoodFoodType

var program = (from p in mEntities.Programs
              where p.Id ==Id
              select new {
                 Program = p,
                 ProgramFoodTypes = from pf in p.ProgramFoodTypes
                                    where pf.IsActive
                                    select pf,                  
                 ProgramFoods = p.ProgramFoods // here i can't add include statement
              }).ToArray().Select(m => m.Program);

如何在第二个查询中包含食物和食物类型?

【问题讨论】:

    标签: c# asp.net-mvc entity-framework ef-code-first


    【解决方案1】:

    对于您的第二个解决方案,我认为您可以使用:

    var program = (from p in mEntities.Programs
                      .Include(p => p.ProgramFoods.Select(f => f.Food))
                      .Include(p => p.ProgramFoods.Select(f => f.FoodType))
                   where p.Id == Id
                   select new {
                      Program = p,
                      ProgramFoodTypes = from pf in p.ProgramFoodTypes
                                         where pf.IsActive
                                         select pf,                  
                      p.ProgramFoods 
                   }).ToArray().Select(m => m.Program);
    

    更新: 由于您在 linq 查询中使用匿名类型,Include statements are dismissed.
    您必须在客户端加载所有相关的ProgramFoodTypes,然后进行过滤:

    var program = mEntities.Programs
                       .Include(p => p.ProgramFoodTypes)
                       .Include(p => p.ProgramFoods.Select(f => f.Food))
                       .Include(p => p.ProgramFoods.Select(f => f.FoodType))
                       .SingleOrDefault(m => m.Id == Id);
    
    program.ProgramFoodTypes = program.ProgramFoodTypes.Where(pft => pft.IsActive);  
    

    您可以使用AsNoTracking() 或将返回的Program 对象克隆到一个新对象中,以确保您的数据在数据库端完好无损。

    【讨论】:

    • 结果中的 Food 和 FoodType 仍然为空
    • 啊,我明白了。那是因为您选择了匿名对象而不是实体本身。更新我的答案...
    • 我试图避免拆分查询并使其变得简单,缺少的部分是我可以在匿名子查询中包含食物和食物类型,正如@tschmit007 在他的回答中提到的那样,谢谢你的更新,我认为它会工作,因为它被分裂了。
    【解决方案2】:

    可能是:

    var program = (from p in mEntities.Programs
              where p.Id ==Id
              select new {
                 Program = p,
                 ProgramFoodTypes = from pf in p.ProgramFoodTypes
                                    where pf.IsActive
                                    select pf,                  
                 ProgramFoods = p.ProgramFoods.Select(y => new {
                     Food = y.Food,
                     Type = y.FoodType
                 }) 
              }).ToArray().Select(m => m.Program);
    

    【讨论】:

    • 它工作正常,只是我自己添加了 ProgramFood,否则将无法检索,谢谢
    【解决方案3】:

    试试这个:

    var program = mEntities.Programs
                           .Include(p => p.ProgramFoodTypes)
                           .Include(p => p.ProgramFoods.Select(f => f.Food))
                           .InClude(p => p.ProgramFoods.Select(f => f.FoodType))
                           .SingleOrDefault(m => m.Id == Id && m.ProgramFoodTypes.All(t => t.IsActive));
    

    【讨论】:

    • 它返回 System.NullReferenceException(对象引用未设置为对象的实例)。
    • 如果您的意思是program 为空,那是因为没有找到符合条件的结果。
    • 我认为 OP 试图实现的是获取对象,但只有相关 ProgramFoodTypes 的 IsActive 设置为 true。
    • 我得到了正常的结果,但不像我删除 m.ProgramFoodTypes.All(t=>t.IsActive) 时想要的那样,似乎在实际包含实体之前应用了 where 子句?像这样的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 2022-02-15
    • 1970-01-01
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多