【问题标题】:Creating a LINQ Expression that goes over more tables创建一个遍历更多表的 LINQ 表达式
【发布时间】:2015-04-21 23:56:16
【问题描述】:

我在构建 Linq 表达式时遇到问题,我现在将解释问题

我有 4 个表格(模型),它们以非常简单的方式看起来像这样:

用户
用户ID(PK)
用户名(字符串, 非空)


UserInEvent
UserInEventID (PK)
UserID (FK, NOT NULL)
EventID (FK, NOT NULL)


Event
EventID (PK)
EventName(字符串, 非空)


UserInTraining
UserInTrainingID (PK)
UserID (FK, NULL)
EventID (FK, NOT NULL)
Username (string, 非空)


现在你应该知道一些事情:

  • 注册用户可以添加到事件 (UserInEvent) 和培训 (UserInTraining)

  • 已注册的用户可以参加作为活动一部分的培训 (UserInTraining),而无需在活动中注册 (UserInEvent)

  • 未注册的用户可以参加作为活动一部分的培训 (UserInTraining),而无需在活动中注册 (UserInEvent)

  • 未注册用户不能在未注册用户的情况下参与事件 (UserInEvent)


现在我的 LINQ 表达式应该获取“UsersInTraining”中但不在“UserInEvent”中的所有“用户”和“未注册用户”,然后返回一个匿名类型(也可以创建一个模型),看起来像这样:

UsersInTrainingButNotInEvent
事件名称
用户名
IsUser (bool, false im not registered)
Username (string, 空)

这是我的表达方式(据我所知):

from usr in _userService.GetAllUsers()
                join tr in _trainingService.GetAllTrainings() on usr.userID equals tr.userID into
                    usersInTraining
                join usrTr in _eventService.GetAllEvents() on usr.userID equals
                    usrTr.userID into usersInEvents

但从这里开始,我不知道如何继续并在 LINQ 表达式中执行我的逻辑:

  1. 让所有用户参与培训
  2. 获取事件中的所有用户
  3. 获取所有在培训中但未在事件中注册的用户,以及未在“用户”中注册但在培训中的用户
  4. 返回具有上述详细信息的匿名类型或模型

    我也对更好的策略持开放态度,但我无法更改表格,因为必须如此。感谢您的帮助!

【问题讨论】:

    标签: c# asp.net-mvc linq


    【解决方案1】:

    您的表达式缺少 select 命令,您的 LINQ 不知道从您创建的缓冲区中选择什么。 尝试类似

    var result = from usr in _userService.GetAllUsers()
                    join tr in _trainingService.GetAllTrainings() on usr.userID equals tr.userID into
                        usersInTraining
                    join usrTr in _eventService.GetAllEvents() on usr.userID equals
                        usrTr.userID into usersInEvents 
                 select new { Username = usr.Username, EventName = usrTr.EventName /* Select other values here */ };
    if(result.Any()) {
        for(int i = 0; i < result.Count; i++) {
            Debug.WriteLine("User: {0} / Event {1}", result[i].Username, result[i].EventName);
        }
    }
    

    “select new {}”中的内容是创建一个新的匿名对象实例,您可以添加任何您想要的内容,并且它们的类型在 C# 中是隐式已知的,当您说“result.Username”时,它会自动假定为 .用户名与 User.Username 的类型相同。我相信这是在编译时完成的。

    哦,是的,我差点忘记了指向 Join Clause 参考的快速链接,可能有用。

    【讨论】:

    • 谢谢这两个解决方案都很棒,让我更好地理解它。这个更适合我,但都得到了投票!
    【解决方案2】:

    让所有用户参与培训

    var usersintraining = from c in UserInTraining
                    select new
                    {
              //Since you already have the FK relationship
              UserName = c.Users.Where(e => e.UserID)
                    };
    

    PS:UserInTraining 中不需要 UsernameUsers 表中已经有了它


    在事件中获取所有用户

    var usersinevents = from c in UserInEvents
                    select new
                    {
              //Since you already have the FK relationship
              UserName = c.Users.Where(e => e.UserID)
                    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-04
      • 1970-01-01
      • 2019-03-01
      相关资源
      最近更新 更多