具有多个相同类型但具有不同限制的列表属性的类

时间:2013-09-04 11:39:40

标签: c# linq entity-framework

这是我的问题:我有一个类有2个相同类类型的列表属性(但是对于如何填充有一些不同的限制),让我们说:

public class Team 
{
    [Key]
    public int IDTeam { get; set; }

    public string TeamName { get; set; }

    public List<Programmer> Members { get; set; }

    public List<Programmer> Leaders { get; set; }

    public LoadLists(MyProjectDBContext db) 
    {
        this.Members = db.Programmers.Where(p => p.IDTeam = this.IDTeam 
                 && (p.Experience == "" || p.Experience == null)).ToList();

        this.Leaders = db.Programmers.Where(p => p.IDTeam = this.IDTeam 
                 && (p.Experience != null && p.Experience != "")).ToList();
    }
}

public class Programmer 
{
    [Key]
    public int IDProgrammer { get; set; }

    [ForeignKey("Team")]
    public int IDTeam { get; set; }
    public virtual Team Team { get; set; }

    public string Name { get; set; }

    public string Experience { get; set; }
}

在某些时候,我需要列出一些团队,包括团队成员和领导者,为此我会假设:

return db.Teams
    .Include(m => m.Members.Where(p => p.Experience == "" || p.Experience == null)
    .Include(l => l.Leaders.Where(p => p.Experience != null && p.Experience != "")
    .OrderBy(t => t.TeamName)
    .ToList();

当然,在这种情况下,我会假设它是错误的(因为它根本不起作用)。 关于如何实现这一点的任何想法?

编辑:为了进一步澄清,团队类的2个列表属性应根据以下内容填写:

1 - 成员属性 - 应包括没有经验的所有相关proggramers(proggramer.Experience == null或“”);

2 - 领导者属性 - 应该包括所有相关的proggramers有任何经验(programmer.Experiente!= null也不是“”);

编辑2:这是MyProjectDbContext声明:

public class MyProjectDBContext : DbContext
{
    public DbSet<Team> Teams { get; set; }
    public DbSet<Programmer> Programmers { get; set; }
}

2 个答案:

答案 0 :(得分:1)

你在谈论EntityFramework(Linq to entities)对吗?如果是这样,Include()是Linq To Entities的方法,以在结果集中包含子关系。我认为你应该把Where()放在Inlcude()之外。

this topic上,您会找到一些关于如何使用Include()方法的示例。

所以我建议首先添加Include()来包含关系“Members”和“Leaders”,然后应用你的Where-Statement(可以用一个Where()完成。)

return db.Teams
    .Include("Team.Members")
    .Include("Team.Leaders")
    .Where(t => string.IsNullOrWhitespace(t.Members.Experience) ... )

我不清楚的是,当你在谈论获得领导者和成员的团队名单时,你的标准和用例是什么。以上示例将返回与Where()语句匹配的团队列表。您可以查看它,在该循环中,您可以列出其成员和领导者 - 如果这是用例。

替代方案是这样的:

return db.Members
    .Where(m => string.IsNullOrWhitespace(m.Experience))
    .GroupBy(m => m.Team)

这将为您提供没有按团队分组经验的成员列表。您可以循环组(团队)及其成员。如果你想让每个团队只有一次,你可以在最后添加一个Distinct(m =&gt; m.Team)。

希望这会有所帮助。如果您需要更详细的代码示例,将有助于更好地了解您的要求。所以,也许你可以再多说一下你对查询的期望。

<强>更新

请阅读我们的编辑,听起来很有趣。我不认为你可以在一个Linq-To-Entities声明中完成所有这些。我个人会在属性成员和领导者的getter上做这个,他们做自己的查询(作为只读属性)。为了获得巨大数据量的性能,我甚至可以使用DB本身的SQL视图来实现。但这取决于使用“会员”和“领导者”的背景(高频率等)。

更新2:

使用单个查询来获取包含成员和领导者子列表的团队表我将对“程序员”进行查询,并将他们按团队和经验嵌套。结果是具有程序员的组(经验/非经验)的组(=团队)列表。然后可以使用三个嵌套的foreach语句构建最终表。有关某些分组示例,请参阅here(请参阅示例“GroupBy - 嵌套”)。

答案 1 :(得分:0)

无论何时获取实体,它们都将存储在上下文中 - 无论它们被“选中”的形式如何。这意味着您可以将团队连同所有必需的相关实体一起提取到匿名类型中,如下所示:

var teams =
    (from team in db.Teams
     select new {
         team,
         relatedProgrammers = team.Programmers.Where(
                                   [query that gets all leaders OR members])
     }).ToList().Select(x => x.team);

看起来我们在这里丢弃relatedProgrammers字段,但那些Programmer实体仍在内存中。所以,当你执行这个时:

foreach (var team in teams) team.LoadLists(db);

...它将从已经获取的程序员填充列表,而不再次查询数据库(假设db与上面的上下文实例相同)。

注意:我自己没有测试过。它基于this answer中显示的类似技术。

编辑 - 实际上,您的“领导者”和“成员”似乎涵盖与团队相关联的所有程序员,因此您应该能够{{ 1}}然后Teams.Include(t => t.Programmers)