Linq - 当"不支持对本地集合的查询"时该怎么办



我正试图将SQL查询转换为Linq,我得到一个异常:

系统。NotSupportedException:不支持本地集合查询。

那么是否有一种方法可以以"合法"的方式重新表达查询?

谢谢你的建议,

安德斯,丹麦

PS:我已经看到了在调用。contains()之前在任何查询上调用。tolist()的"解决方案"——但这只会导致四个单独的查询,对吧?

下面是执行失败的代码。

我试图解决的逻辑问题是找到用户可以访问的"结构",无论是通过直接访问还是通过具有访问权限的组的成员。我们没有嵌套的组

换句话说,如果满足以下任何一个条件,用户应该具有访问权限:

  • 用户创建结构(id被"戳入"结构记录)。
  • PermissionUsers表中存在一条表项,连接Permissions表和users表。
  • PermissionGroups表中存在一个条目,将Permissions表与Groups表连接起来,并在其中引用用户UsersGroups表,连接Users表和Users表。

对可访问的项应用权限/限制结果是一个相对较新的事情,我们希望数据库做繁重的工作;)。

[TestFixture]
public class LinqTest : CommandBasedIntegrationTestBase
{
    [Test, Category("SuperIntegration"), RequiresSTAAttribute]
    public void TestThat()
    {
        DbIntegrationTestHelper.SetState();
        var dataContextProvider = ObjectFactory.GetInstance<IDataContextProvider>();
        const int userId = 1;
        var environment = ObjectFactory.GetInstance<IState>().DatabaseEnvironment;
        var dataClasses1DataContext = dataContextProvider.GetContext(environment);
        var idsByCreator = from r in dataClasses1DataContext.Structures where r.CreatedUserId == userId select r.StructureId;
        var idsByUserAccess = from r in dataClasses1DataContext.PermissionUsers where r.UserId == userId select r.StructureId;
        var idsOfGroupsContainingUser = from r in dataClasses1DataContext.UsersGroups where r.UserId == userId select r.GroupId;
        var idsByGroupAccess = from r in dataClasses1DataContext.PermissionGroups where idsOfGroupsContainingUser.Contains( r.GroupId ) select r.StructureId;

        var res = from s in dataClasses1DataContext.Structures
                  where
                      idsByCreator.Contains(s.StructureId) || 
                      idsByUserAccess.Contains(s.StructureId) ||
                      idsByGroupAccess.Contains(s.StructureId)
                  select s;
        foreach (var structure in res)
        {
            Debug.WriteLine(structure.Name);
        }
    }
}

尝试JOIN s, UNION s

var ctx = dataContextProvider.GetContext(environment);
var byCreator = from r in ctx.Structures where r.CreatedUserId == userId select r;
var byUserAccess = from r in ctx.PermissionUsers 
                   join s in ctx.Structures on r.StructureId equals s.StructureId
                   where r.UserId == userId select s;
var byGroups = from ug in ctx.UsersGroups 
               join pg in ctx.PermissionGroups on ug.GroupId equals pg.GroupId
               join s in ctx.Structures on pg.StructureId equals s.StructureId
               where ug.UserId == userId select s;
var res = byCreator.Union(byUserAccess).Union(byGroups);

更新

我已经根据@Magnus的评论删除了不必要的Distinct()呼叫。只有当使用Concat()而不是Union()时,才需要调用Distinct()

正如我所看到的,你正试图找到s。StructureId在数据库表中,你把它们带到应用层。

也许你最好把你所有的登录在SQL函数或SP和得到最终结果只到应用层?

相关内容

  • 没有找到相关文章

最新更新