2015-04-29 75 views
1

我有功能聯盟對空可枚舉

public async Task<IQueryable<Document>> GetDocuments(...) 

我在其中尋找一些特定條件下的文檔。有些情況可以跳過。最後,我執行這些查詢的聯合。

var documents = await documentService.GetDocuments(this, userId, 
       roleShowFullNumber, param.OrderColName(), param.SearchValue, filter); 
    var usersGroupsId = filter.UsersGroupsId; 
     if (usersGroupsId != null) 
     { 
      if (!usersGroupsId.Contains("All")) 
      { 
       IQueryable<Document> myDocs = Enumerable.Empty<Document>().AsQueryable(); 
       if (usersGroupsId.Contains("myOrders")) 
       { 
        myDocs = documents.Where(x => x.OwnerId == userId || x.UserId == userId); 
        usersGroupsId = usersGroupsId.Where(x => x != "myOrders").ToArray(); 
       } 
       IQueryable<Document> wards = Enumerable.Empty<Document>().AsQueryable(); 
       if (usersGroupsId.Contains("wards")) 
       { 
        var relatedUserId = _db.Users.Where(x => x.Id == userId).Select(x => x.RelatedUserId).FirstOrDefault(); 
        if (relatedUserId != null) 
        { 
         var myWards = _db.kh__Kontrahent.Where(x => x.kh_IdOpiekun == relatedUserId); 
         var myWardsUsers = _db.Users.Where(x => myWards.Any(w => w.kh_Id == (x.RelatedCustomerId == null ? -1 : x.RelatedCustomerId))); 
         wards = documents.Where(x => (myWardsUsers.Any(w => x.UserId == w.Id) || myWardsUsers.Any(w => x.OwnerId == w.Id))); 
         usersGroupsId = usersGroupsId.Where(x => x != "wards").ToArray(); 
        } 
       } 

       IQueryable<Document> groups = Enumerable.Empty<Document>().AsQueryable(); 
       if (usersGroupsId.Length > 0) 
       { 
        var usersGroups = _db.Groups.Where(x => usersGroupsId.Contains(x.Id.ToString())); 
        var usersList = usersGroups.Select(x => x.Users); 
        var users = usersList.SelectMany(x => x); 
        var usersId = users.Select(x => x.Id); 
        groups = _db.Documents.Where(x => (usersId.Any(u => u == x.OwnerId) || usersId.Any(u => u == x.UserId))); 
       } 

       documents = myDocs.Union(wards).Union(groups); 

      } 
     } 

但是如果這些部分查詢的一個是空的(被跳過)當我試圖得到如下圖所示我得到了錯誤的方式這些文件。

var documentsPaginated = await documents.Skip(param.Start) 
            .Take(param.Length) 
            .ToListAsync(); 

錯誤:源IQueryable未實現IDbAsyncEnumerable。

我該如何使這個函數能夠跳過一些子查詢,然後聯合所有。我寧願不改變函數返回值。

回答

1

試試這個,althought你的代碼似乎有代碼味道了大量的...

public async Task<IQueryable<Document>> GetDocuments(...)  
    var documents = await documentService.GetDocuments(this, userId, 
       roleShowFullNumber, param.OrderColName(), param.SearchValue, filter); 
    var usersGroupsId = filter.UsersGroupsId; 
     if (usersGroupsId != null) 
     { 
      if (!usersGroupsId.Contains("All")) 
      { 
       IQueryable<Document> myDocs = null; 
       if (usersGroupsId.Contains("myOrders")) 
       { 
        myDocs = documents.Where(x => x.OwnerId == userId || x.UserId == userId); 
        usersGroupsId = usersGroupsId.Where(x => x != "myOrders").ToArray(); 
       } 
       IQueryable<Document> wards = null; 
       if (usersGroupsId.Contains("wards")) 
       { 
        var relatedUserId = _db.Users.Where(x => x.Id == userId).Select(x => x.RelatedUserId).FirstOrDefault(); 
        if (relatedUserId != null) 
        { 
         var myWards = _db.kh__Kontrahent.Where(x => x.kh_IdOpiekun == relatedUserId); 
         var myWardsUsers = _db.Users.Where(x => myWards.Any(w => w.kh_Id == (x.RelatedCustomerId == null ? -1 : x.RelatedCustomerId))); 
         wards = documents.Where(x => (myWardsUsers.Any(w => x.UserId == w.Id) || myWardsUsers.Any(w => x.OwnerId == w.Id))); 
         usersGroupsId = usersGroupsId.Where(x => x != "wards").ToArray(); 
        } 
       } 

       IQueryable<Document> groups = null; 
       if (usersGroupsId.Length > 0) 
       { 
        var usersGroups = _db.Groups.Where(x => usersGroupsId.Contains(x.Id.ToString())); 
        var usersList = usersGroups.Select(x => x.Users); 
        var users = usersList.SelectMany(x => x); 
        var usersId = users.Select(x => x.Id); 
        groups = _db.Documents.Where(x => (usersId.Any(u => u == x.OwnerId) || usersId.Any(u => u == x.UserId))); 
       } 
       if(myDocs != null) 
        documents = documents.Union(myDocs); 
       if(wards != null) 
        documents = documents.Union(wards); 
       if(groups != null) 
        documents = documents.Union(groups); 

      } 
     } 
+0

謝謝,沒想到:) – Paulie

0

似乎ToListAsync不能與linq交換使用,但只能在EF查詢中使用。

報價從MSDN

Entity Framework 6 introduced a set of extension methods that can be used to asynchronously execute a query. Examples of these methods include ToListAsync, FirstAsync, ForEachAsync, etc.

Because Entity Framework queries make use of LINQ, the extension methods are defined on IQueryable and IEnumerable. However, because they are only designed to be used with Entity Framework you may receive the following error if you try to use them on a LINQ query that isn’t an Entity Framework query.

The source IQueryable doesn't implement IDbAsyncEnumerable{0}. Only sources that implement IDbAsyncEnumerable can be used for Entity Framework asynchronous operations. For more details see http://go.microsoft.com/fwlink/?LinkId=287068 .

+0

所以我應該怎樣分配空查詢到這些空的子查詢這麼即使他們被跳過,我也可以執行聯合? – Paulie