繁体   English   中英

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

[英]Class with multiple List Properties of same type but with different restrictions

这是我的问题:我有一个类,该类具有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-成员属性-应包括没有经验的所有相关编程器(proggramer.Experience == null或““);

2-领导者属性-应包括具有任何经验的所有相关编程器(programmer.Experiente!= null或““);

编辑2:这是MyProjectDbContext声明:

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

您是在谈论EntityFramework(实体的Linq),对吗? 如果是这样,则Include()是Linq To Entities的一种方法,可在结果集中包含子关系。 我认为您应该将Where()放在Inlcude()之外。

该主题上,您将找到一些有关如何使用Include()方法的示例。

因此,我建议首先添加Include()以包括“成员”和“领导者”关系,然后应用您的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 => m.Team)。

希望这可以帮助。 如果您需要一些更详细的代码示例,则有助于更好地了解您的要求。 因此,也许您可​​以对查询的期望再说几句话。

更新:

只需阅读我们听起来很有趣的编辑即可。 我认为您无法在一个Linq-To-Entities语句中完成全部操作。 就个人而言,我会在成员和领导者属性的获取器上执行此操作,这些属性将执行自己的查询(作为只读属性)。 为了获得海量数据的性能,我什至可以使用数据库本身的SQL视图来实现。 但这在某种程度上取决于所使用的“成员”和“领导者”的上下文(频繁出现等)。

更新2:

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

每当您获取实体时,它们都会存储在上下文中-不管“选择”它们的形式如何。这意味着您可以将团队以及所有必要的相关实体获取为匿名类型,如下所示:

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与上面的上下文实例相同)。

注意:我自己尚未测试过。 它基于此答案中显示的类似技术。

编辑 -实际上,您的“领导者”和“成员”似乎覆盖与团队相关的所有程序员,因此您应该能够只使用Teams.Include(t => t.Programmers) ,然后执行LoadLists

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM