我正在尝试将SQL查询转换为Linq,但我得到一个例外:
System.NotSupportedException:不支持使用本地集合的查询。
那么有没有办法以'合法'的方式重新调整查询?
感谢您的任何建议,
丹麦安德斯
在底部是我的代码在执行时失败。
我正在尝试解决的逻辑问题是找到用户可以访问的“结构”,可以是直接访问,也可以是具有访问权限的组的成员身份。我们没有嵌套组。
换句话说,如果满足以下任何条件,用户应该有权访问:
- 用户创建了结构(id被'标记'到结构记录中。)
- PermissionUsers表中存在一个条目,将权限表与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);
}
}
}
答案 0 :(得分:1)
尝试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()
的不必要的调用。仅在使用Distinct()
而非Concat()
时才需要致电Union()
。
答案 1 :(得分:0)
我可以看到您正在尝试在数据库表中找到 s.StructureId ,并将它们带到应用层。
也许你最好在SQL Function或SP中推送所有的loginc,并将最终结果只传递给应用层?