【问题标题】:complex query using LINQ and C#使用 LINQ 和 C# 的复杂查询
【发布时间】:2009-01-31 04:06:25
【问题描述】:

我有一个非常大的问题来解决这个问题 我有两张桌子

第一个表是: http://lh3.ggpht.com/_uMvfbnPHuko/SYPJQ1ZsBDI/AAAAAAAAAKs/eq49xquy3jM/s800/Untitled-2.jpg

其中包含一个模块(id 和名称)

第二张桌子是 http://lh6.ggpht.com/_uMvfbnPHuko/SYPJQ4IXGwI/AAAAAAAAAK0/zmTIO6V-UEQ/s800/Untitled-3.jpg

其中包含用户 ID 及其首选模块的编号

现在让我们来解决问题 我想生成一个复选框列表

例如对于具有以下模块“3,2 和 4”的用户 ID 1 结果将是

http://lh4.ggpht.com/_uMvfbnPHuko/SYPJQ_LJeVI/AAAAAAAAAK8/6RV8a1S8eCY/s800/Untitled-4.jpg

请注意,未选中“为您推荐”复选框,因为用户 1 没有模块 ID“1”

我花了很长时间尝试使用 c# 和 LINQ 解决这个问题

看看我努力的结果:)(下面的代码不起作用)

    var q = from m in db.modules
            from um in db.usersModules.Where(um2 => um2.userId == myUserId).Single().modules.Trim().Split(',')
            where um.Contains(m.moduleId.ToString())
            select new
            {
                moduleid = here i want the module id from modules table
                modulename = here i want the modulename from modules table
                ischecked = here i want "true" or "false" depending on if the user has this module or not

            };

如果 LINQ 对您来说很简单,请尝试解决这个问题? 有什么问题吗?

【问题讨论】:

    标签: c# asp.net database linq


    【解决方案1】:

    您的查询不起作用,因为 LinqToSQL 试图将所有内容都转换为纯 SQL。

    如果您无法重构架构并使用中间表,因为您显然具有多对多关系,您可以执行以下操作:

    var userModules = db.userModules.SingleOrDefault(m => m.userId == myUserId).modules;
    // Get the modules of the user (a comma delimited string)
    var integerModules = modules.Split(',').Select(m => int.Parse(m));
    // Convert the comma delimited string to IEnumerable<int>
    
    var query = db.modules.Select(x => new {
                    x.moduleId,
                    x.moduleName,
                    isChecked = integerModules.Contains(x.moduleId)
    }); // And finally do the query
    

    【讨论】:

    • 谢谢哥们,它有效!,我已经尝试了很长时间,终于感谢了:)
    • 不错的 CMS :) Ahmed,你应该重构你的数据库模式。将 2,3,4 作为数据是不好的。使用一对多的桌子……这是海事组织的正确做法。
    • 谢谢 Pure.Krome,我也同意你的观点,ahmed,你应该在用户和模块之间使用链接表,如果你想跟踪顺序(userId,moduleId,number),你可以添加一个整数字段来做到这一点,查询会更容易......
    【解决方案2】:

    您为什么使用逗号分隔的列表?更好的方法是在其中存储用户和模块之间的映射的表。

    【讨论】:

    • 我同意你的观点,但我选择这个数据库模型是为了能够为每个用户存储模块的顺序,例如用户 1 的模块顺序为 3,2,4
    • @ahmed:您仍然可以存储订单,您只是在映射表中有另一列包含订单并按升序填充。
    【解决方案3】:

    如果可以,最好重构您的表,而不是尝试以它所在的格式处理数据。

    在您的“usersModule”表中,如果您将模块列更改为“moduleId”并为与 userId 关联的每个模块插入一条记录,您将更容易查询我认为的数据和您的数据库会更容易维护。

    Table: "modules"
    moduleId    moduleName
    1           Recommended...
    2           Blah
    3           ...
    
    Table: "usersModule"
    userId      moduleId
    1           3
    1           2
    1           4
    

    【讨论】:

    • 我同意,但我选择这个数据库模型是为了能够为每个用户存储模块的顺序,例如用户 1 的模块顺序为 3,2,4
    • 您可以在表格中添加另一列,例如“订单”,您可以在其中存储该用户的模块排名。您真的不应该将逗号分隔的 ID 列表放在一列中,这会使查询变得非常困难。
    • 我同意分离列会很容易查询,但它只是一个查询,最后它解决了
    【解决方案4】:

    如果可以选择,您可能需要重构数据库架构。您的 usersModule 表每行应该有一个用户 ID 和一个模块 ID,并且 moduleId 列应该是模块表的外键。如果你这样做,linq 查询将是微不足道的。

    如果您按原样使用数据库,您可能会遇到两个查询:一个用于检索模块 ID 的查询,另一个用于检索实际模块信息的查询。

    【讨论】:

      【解决方案5】:

      我想应该是这样的,但是您没有提供有关您的数据库结构的足够准确信息,我无法准确地编写查询。

      var q =
          from m in db.modules
          select new {
              m.moduleId,
              m.name,
              db.usersModules.Exists(um => um.userId == myUserId)
          };
      

      编辑:哦,我刚刚意识到你有一个逗号分隔的东西。就像其他人所说的那样,首先正确地重新排列您的数据库。

      【讨论】:

      • 我收到此错误“usersModules 没有 Exists 和扩展方法的定义”?
      • 好吧,我不会为你写代码!我只是说可以这样做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多