【问题标题】:Entity Framework Filtering On GrandChildren实体框架过滤 GrandChildren
【发布时间】:2013-01-25 14:40:29
【问题描述】:

对于实体框架来说还是很新的。如果这是一个菜鸟问题,请原谅我。希望有人能对此有所了解。

我正在尝试从 3 个相关表中选择数据。

Leagues -> Teams -> Rosters -> 

关系是League.LeagueID => Team.LeagueID => Roster.TeamID

在名册表中有一个PlayerID

我需要一个可以选择名册拥有PlayerID = 1的所有联赛的查询

无论我尝试什么,我似乎都无法过滤孙记录的结果。在互联网上也找不到太多。

我找到了一种使用匿名类型的方法,但这些都是只读的,因此我可以对数据进行更改。我必须能够在它返回后更新数据。

【问题讨论】:

标签: c# frameworks entity


【解决方案1】:
db.Leagues.Where(l => l.Teams.Any(t => t.Roster.PlayerID == 1));

生成的 SQL 应该能得到你想要的,即使它看起来不可读;)

如果您想专门使用内部联接来执行此操作,您可以使用如下代码来执行此操作:

from l in db.Leagues
join t in db.Teams on l.LeagueID equals t.LeagueID
join r in db.Rosters on t.TeamID equals r.TeamID
where r.PlayerID = 1
select l

更新

使用Include() 来处理急切加载子关联:

((from l in db.Leagues
join t in db.Teams on l.LeagueID equals t.LeagueID
join r in db.Rosters on t.TeamID equals r.TeamID
where r.PlayerID = 1
select l) as ObjectQuery<League>).Include(l => l.Teams.Select(t => t.Rosters))

【讨论】:

  • 这不太行。当我查看 sql 时,它会创建左连接并返回太多数据。也许我太简单了。我真正拥有的是4张桌子。 Parent -> Child -> GrandChild -> GreatGrandChild 我想返回所有父母,但过滤孩子和曾孙。换句话说 Select Parent* from Parent inner join Child inner join Grandchild inner join GreatGrandChild where child.Column5 = 600 and GreatGrandChild.Column3 = 1000
  • 添加了另一个选项来执行您想要的查询,这对您有帮助吗?
  • 这似乎有效,但我有一个问题。如果我这样做 foreach (var League in l) { foreach (var team in League.Teams) { foreach (var roster in team.Rosters) { } } } 每个内部循环都会调用数据库吗?我希望立即将所有这些数据带回以减少数据库旅行。
  • 您想要的称为急切加载 - 已更新以包含此内容。通过预先加载,调用 foreach 不会触发数据库命中,因为项目已经加载到关联集合中。
【解决方案2】:
db.Roasters.Where(r=>r.PlayerId ==1).Select(r=>r.Team).Select(t=>t.League).Distinct()

如果 Roaster 有很多球队并且球队有很多联赛,您可以使用 .SelectMany 而不是 .Select

.SelectMany 来自MSDN 的示例:

PetOwner[] petOwners = 
                    { new PetOwner { Name="Higa, Sidney", 
                          Pets = new List<string>{ "Scruffy", "Sam" } },
                      new PetOwner { Name="Ashkenazi, Ronen", 
                          Pets = new List<string>{ "Walker", "Sugar" } },
                      new PetOwner { Name="Price, Vernette", 
                          Pets = new List<string>{ "Scratches", "Diesel" } } };

                // Query using SelectMany().
                IEnumerable<string> query1 = petOwners.SelectMany(petOwner => petOwner.Pets);

【讨论】:

  • 这可能有效,但 SelectMany 出现问题。您有示例吗?
  • 语法应该一样,试试用.SelectMany代替.Select
  • 在您的示例中仅将 Select 替换为 SelectMany 不起作用。编译错误
  • 这可能意味着它在另一边没有多条记录。
  • 是编译错误。如果不运行应用程序,编译器不可能不会在另一端没有多条记录。
猜你喜欢
  • 1970-01-01
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 2019-04-14
  • 2015-12-29
  • 2011-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多