【问题标题】:Is my IQueryable syntax correct?我的 IQueryable 语法是否正确?
【发布时间】:2009-06-26 16:06:23
【问题描述】:

生成的 SQL 执行交叉连接,但随着 ID 的匹配,它的行为类似于内部连接,但是否有更好的执行方式通过在 C# 中实际使用 join 关键字来执行此操作?有没有一种方法可以让您不必指定属性如何连接,因为它们都是层次相关的

Item 是一个 Page 类

PageRoles 是 Page 类中的 IQueryable 属性

aspnet_Roles 是 PageRole 类中的 IQueryable 属性

var item = _repository.GetByKey(999);

var f = (from fd in item.PageRoles 
         from k in fd.aspnet_Roles 
         where Roles.GetRolesForUser().Contains(k.RoleName) 
         && k.RoleId == fd.RoleId 
         select k.RoleName)
        .Count();

编辑:

这是我的类中的 IQueryable 属性的示例。下面的例子来自PageRole类

public IQueryable<aspnet_Role> aspnet_Roles
{
    get
    {

          var repo=NorthCadburyWebsite.Models.aspnet_Role.GetRepo();
          return from items in repo.GetAll()
               where items.RoleId == _RoleId
               select items;
    }
}

【问题讨论】:

    标签: asp.net-mvc linq subsonic subsonic3


    【解决方案1】:

    这是编译还是出错?

    在这种情况下,正如您所提到的,您不需要加入。 这个语法我没用过,但是看起来你用k作为引用(就像sql语法中的别名)

    这应该会产生相同的结果(甚至不使用 k):

    var f = (from fd in item.PageRoles 
             where Roles.GetRolesForUser().Contains(fd.aspnet_Roles.RoleName) 
             && fd.aspnet_Roles.RoleId == fd.RoleId 
             select fd.aspnet_Roles.RoleName)
            .Count();
    

    注意:未经测试,只是猜测。

    【讨论】:

    • 不能做 fd.aspnet_Roles.RoleName 因为 fd.aspnet_Roles 是 IQueryable 并且不是类的实例
    【解决方案2】:

    我没有智能感知,但我认为你可以:

    var f = (from fd in item.PageRoles 
             join k in fd.aspnet_Roles on k.RoleId equals fd.RoleId
             where Roles.GetRolesForUser().Contains(k.RoleName) 
             select k.RoleName)
            .Count();
    

    【讨论】:

    • 将 == 更改为等于,您必须交换 fd.RoleId 在左侧,k.RoleId 在右侧,但是是的,我相信这是正确的。我仍在努力了解连接的目的和层次结构......
    • 你不能在 fd.aspnet_Roles 中加入 k,因为由于某种原因它无法识别 fd...?
    • 我认为我第一次是对的...... K.RoleID 在 equals 之前排在第一位。
    【解决方案3】:

    我想我很困惑,因为我在您的查询中看到以下层次结构,这没有任何意义:

    [页面角色] |--角色标识

    层次结构是由RoleId 决定的,而你的意思是PageRoles.RoleId 引用aspnet_Roles.RoleId?所以你可能会有类似的东西:

    [PageRoles] [aspnet_Roles] |--角色ID |--角色ID |--角色名

    而您正试图将其变为以下内容:

    [页面角色] |--角色标识 |--[aspnet_Roles](其中 RoleId == PageRoles.RoleId) |--角色名

    ...?


    在这种情况下,如果您不能执行以下操作,那么 您的 IQueryable 属性定义有问题 而不是您发布的查询。即获取PageRolesaspnet_Roles子行的方法设置不正确。

    var f = (from fd in item.PageRoles 
             from k in fd.aspnet_Roles 
             where Roles.GetRolesForUser().Contains(k.RoleName) 
             select k.RoleName)
            .Count();
    

    fd.aspnet_Roles 应该已经被RoleId 约束并生成一个内部连接)。

    您可以通过查看生成的 SQL 来检查您的层次结构:

    var f = from fd in item.PageRoles
            from k in fd.aspnet_Roles
            select k;
    

    应该有点像(与放入的物品有关):

    SELECT k.RoleName, k.SomethingElse
    FROM PageRoles fd
    INNER JOIN aspnetRoles k ON fd.RoleId = k.RoleId;
    

    我确定我遗漏了什么,所以请帮我填空...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-14
      • 1970-01-01
      • 1970-01-01
      • 2018-03-20
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      相关资源
      最近更新 更多