Linq查询业务对象以发现唯一记录.这是递归的情况吗

本文关键字:递归 情况 记录 唯一 业务 查询 对象 发现 Linq | 更新日期: 2023-09-27 18:03:50

不知道该怎么做,希望这里的聪明人能给我指出正确的方向。我有一个业务对象,它是一个集合,当然,顶级集合中的每个项目都有一些属性,但其中一个属性是一些相关子记录的集合....并且这些子记录具有我正在寻找的值。

所以这是高层次的概述,没有更接近。

父对象是事件的集合(本质上是学校的类),相关的子集合是教员…这样一个主要的、次要的、辅助的、观察者等

现在我们的想法是创建一个教师日历,显示Bob…等在这个月有什么活动

因此教师将在日历的左侧(Y轴),而每个月的日期将在顶部(X轴)....然而,正如我提到的,教员必须从业务对象中挖掘出来。

现在我处于开发阶段,如果有更好的方法我应该实现,我可以重新工作这个业务对象。


现在在我有限的知识库中,我能想到的最好的方法是编写一个foreach循环来提取一次查询一个的指导员…将结果添加到另一个集合,然后获取新的集合并删除重复或重复检查,并且在循环期间不插入。

类似于列表。ForEach(x => x. teammember ....??)

父对象:

public class CalendarEvent
{
    #region Internal Fields
        private readonly string _id;
        private DateTime _start;
        private DateTime _end;
        private string _eventname;
        private TeamMembers _eventteam;
    #endregion
    #region Const
        public CalendarEvent(string id, DateTime start, DateTime end, string evtname)
        {
            this._id = id;
            this._start = start;
            this._end = end;
            this._eventname = evtname;
        }
    #endregion
    #region Props
        public string ID { get { return _id; } }
        public DateTime Start { get { return _start; } }
        public DateTime End { get { return _end; } }
        public string EventName { get { return _eventname; } }
        public TeamMembers EventTeamMembers { get; set; }

    #endregion
}

子对象TeamMembers:

public class TeamMember
{
    #region Internal Fields
        private readonly string _firstname;
        private readonly string _fullname;
        private readonly string _userid;
        private TeamRoles.TeamMemberRole _memberrole;
        //private string _resid;
    #endregion
    #region Const
        public TeamMember(string fullname, string firstname, string userid)
        {
            this._fullname = fullname;
            this._firstname = firstname;
            this._userid = userid;
            //this._resid = resid;
        }
    #endregion
    #region Props
        public string FirstName { get { return _firstname; } }
        public string FullName { get { return _fullname; } }
        public string UserId { get { return _userid; } }
        //public string SpeakerID { get { return _resid; } }
        public TeamRoles.TeamMemberRole TeamMemberRole { get; set; }
    #endregion
}

所以对象看起来是这样的:

CalendarEvent.Count = 25
CalendarEvent[0]
   EventId = GUID
   Start = May 1st
   End = May 12th
   EventName = Pencil Sharpening
   TeamMembers(.count = 3)

所以我需要提取所有三个团队成员,但是如果我已经将他们添加到Y轴集合(即将绑定到Y轴的集合),那么稍后使用List.Distinct()或类似方法跳过或删除。

任何想法、建议或最佳实践都将非常感谢。


我很抱歉,但我正在挣扎于向我展示的一个方面。我相信@ Ben Aaronson已经回答过这个问题了,但是我不太明白。

我理解事件了解TeamMembers的评论,但不是相反。我也理解这句话:

"你需要把所有的事件存储在某个地方。你不可能只从团队成员开始,在没有同时访问事件的情况下获得事件……"

同意,但我确实有这样一个集合,在下面的建议解决方案中称为_allevents…所以我希望能拿出一个独特的团队成员集合。

例如,我写了这个,但我缺乏知识意味着这只是绕着桑树丛旅行....我得到了我已经拥有的??

List<CalendarEvent> asdf = _allevents.Where(evt => evt.TeamMembers.Any(tm => tm.UserId != string.Empty)).Distinct().ToList();

Linq查询业务对象以发现唯一记录.这是递归的情况吗

您的解决方案看起来像这样:

public IEnumerable<CalendarEvent> EventsForTeamMember(string userId)
{
    return _allEvents.Where(e => e.EventTeamMembers.Any(tm => tm.UserId == userId));
}

在本例中,假设您有一个集合,其中包含范围内所有可能发生的事件,称为_allEvents。我也假设TeamMembers是某种TeamMember的集合,你可以在上面执行LINQ查询。如果您想通过用户ID以外的其他方式来查找团队成员,那么这个更改应该相对容易看到。

编辑

要拉出一个不同的团队成员列表,就像你问题的更新部分一样,你已经接近了,但你需要记住,你想要选择团队成员退出事件。所以它看起来像:

public IEnumberable<TeamMember> AllTeamMembersForEvents()
{
    return _allEvents.SelectMany(e => e.EventTeamMembers).Distinct();
}

这里的关键位是SelectMany,它使集合变平。

我将在对象上进行迭代,收集一个新的带有团队成员和日期的匿名对象,使用SelectMany将这些元素"平放"并连接起来——然后按团队成员和日期对它们进行排序。一旦你有了按团队成员和日期排序的列表,你就可以迭代它来构建你的日历,因为项目将按需要的顺序排列。

:

var byMemberDate = events
                    .SelectMany(e => e.EventTeamMembers
                                      .Select(m => new { evnt = e, member = m}))
                    .OrderBy(item => item.member.FullName)
                    .ThenBy(item => item.evnt.Start);
foreach(var item in byMemberDate)
  Console.WriteLine("Member = "+item.member.FullName+" Date = "+item.evnt.Start);
输出:

Member = gi joe Date = 1/1/2014 1:01:01 AM
Member = hogan long Date = 1/1/2014 1:01:01 AM
Member = sam spade Date = 1/1/2014 1:01:01 AM
Member = sam spade Date = 2/2/2014 2:02:02 AM
Member = three three Date = 3/3/2014 3:03:03 AM

完整工作代码在这里https://gist.github.com/hoganlong/1bad5892febf3f48b55f


我想起了一个旁注。如果您想要一个团队成员的列表,每个成员都有一个日期列表,这也很容易。在SelectMany之后使用GroupBy

:

var byMembers = events
                .SelectMany(e => e.EventTeamMembers
                                  .Select(m => new { start = e.Start, name = m.FullName}))
                .GroupBy(item => item.name)
                .OrderBy(g => g.Key);