依靠LINQ联盟

时间:2010-03-25 12:32:36

标签: linq count union

我有这个链接声明:

List<UserGroup> domains = UserRepository.Instance.UserIsAdminOf(currentUser.User_ID);

query = (from doc in _db.Repository<Document>()
         join uug in _db.Repository<User_UserGroup>() on doc.DocumentFrom equals uug.User_ID
         where domains.Contains(uug.UserGroup)
         select doc)
.Union(from doc in _db.Repository<Document>()
       join uug in _db.Repository<User_UserGroup>() on doc.DocumentTo equals uug.User_ID
       where domains.Contains(uug.UserGroup)
       select doc);

运行此语句不会导致任何问题。但是当我想计算结果集时,查询突然运行得很慢。

totalRecords = query.Count();

此查询的结果是:

SELECT COUNT([t5].[DocumentID])
FROM (
    SELECT [t4].[DocumentID], [t4].[DocumentFrom], [t4].[DocumentTo]
    FROM (
        SELECT [t0].[DocumentID], [t0].[DocumentFrom], [t0].[DocumentTo
        FROM [dbo].[Document] AS [t0]
        INNER JOIN [dbo].[User_UserGroup] AS [t1] ON [t0].[DocumentFrom] = [t1].[User_ID]
        WHERE ([t1].[UserGroupID] = 2) OR ([t1].[UserGroupID] = 3) OR ([t1].[UserGroupID] = 6)
        UNION
        SELECT [t2].[DocumentID], [t2].[DocumentFrom], [t2].[DocumentTo]
        FROM [dbo].[Document] AS [t2]
        INNER JOIN [dbo].[User_UserGroup] AS [t3] ON [t2].[DocumentTo] = [t3].[User_ID]
        WHERE ([t3].[UserGroupID] = 2) OR ([t3].[UserGroupID] = 3) OR ([t3].[UserGroupID] = 6)
        ) AS [t4]
    ) AS [t5]

有人可以帮助我提高计数查询的速度吗?

提前致谢!

2 个答案:

答案 0 :(得分:3)

请务必在[Document].[DocumentFrom][Document].[DocumentTo][User_UserGroup].[UserGroupID]上设置索引。

通过阅读您的查询,我可以看到您在不同条件下加入同一张表 如果您不需要重复结果,您可以看看这个替代方案:

var query = from doc in _db.Repository<Document>()
            from uug in _db.Repository<User_UserGroup>() 
            //join wether DocumentFrom or DocumentTo equals User_ID
            where (
                     (doc.DocumentFrom == uug.User_ID) ||
                     (doc.DocumentTo == uug.User_ID)
                  ) &&
                  //same check on this                      
                  domains.Contains(uug.UserGroup)
            select doc;

//execute it
var list = query.ToList();

编辑:如果我没有弄错,.Union会在两个查询之间选择不同的元素,因此我的替代 IS 是有效的。 如果您真的想合并两个结果集,可能需要查看.Concat

答案 1 :(得分:0)

摆脱你的工会并尝试这样的事情。

query = (from doc in _db.Repository<Document>().Where(x=> _db.Repository<User_UserGroup>().Any(y=>y.User_ID==x.DocumentFrom ||y.User_ID==x.DocumentTo ))

对不起,我不能保证它会编译......但基本上可以使用任何一个来完成你的工作。