2016-08-05 87 views
0

我需要做一個像getUsers(列表ID)的查詢; 我需要通過ID搜索,如果找到,然後返回用戶列表中的ID,如果沒有找到,然後返回所有用戶,或者如果發現只有一個返回一個用戶。複雜的查詢與if

如何編寫此查詢?

這是我如何開始:

public List<User> getUsers (List<int> ids)   
{ 
    using(var uow = _repository.CreateUnitOfWork()) 
    {    
     var u = uow.GetEntities<User>().Where(c => c.Id in ids); 
     if (u == null) 
     u.ToList();      
    } 
} 
+0

,我需要使用實體框架 – Ovidiu

回答

2

你的問題是沒有意義的,因爲函數的返回類型必須是相同的。它在某些時候不能返回List,剩下的時間不能返回User

我建議是這樣的:

public IEnumerable<User> GetUsersByIdOrAllUsers(IEnumerable<int> ids) 
{ 
    using (var uow = _repository.CreateUnitOfWork()) 
    { 
     var users = uow.GetEntities<User>(); 

     if (users.Any(c => ids.Contains(c.ID))) 
     { 
      return users.Where(c => ids.Contains(c.ID)); 
     } 

     return users; 
    } 
} 

然後,您可以測試,如果你只找到了一個用戶:

var matchingUsers = GetUsersByIdOrAllUsers(ids); 

if (matchingUsers.Any() && !matchingUsers.Skip(1).Any()) 
{ 
    var singleUser = matchingUsers.Single(); 

    // Do stuff with the single user... 
} 

注意的是,使用IEnumerable使得操作懶惰,因此也更高效。如果你真的一個List,只是做:

var matchingUsersList = matchingUsers.ToList() 
0

不知道是否有一個不太健談的方式做到這一點,但在邏輯上也許這樣的事情?:

if (uow.GetEntities<User>().Any(u => ids.Contains(u.ID)) 
    return uow.GetEntities<User>().Where(u => ids.Contains(u.ID)).ToList(); 
return uow.GetEntities<User>().ToList(); 

我假設這裏uow.GetEntities<User>()只是簡單地返回一個可查詢的數據,並且本身並沒有實現數據庫中的任何內容,或者有任何顯着的性能損失。如果情況並非如此,則此操作的代碼可能需要放在DAL的更深處。

+0

但是這好像你正在執行的條件, – Sherlock

+1

@Sherlock兩次:替代,因爲我看到它是總是實現完整的用戶列表並檢查內存中的條件,而不是根據數據源檢查兩次。這對我來說似乎不太理想。在這兩者之間,檢查條件可能比實現不必要的記錄要便宜。 – David

+0

但是第二次檢查是對第一個輸出進行的(所有不必要的記錄都被過濾掉了),它對我來說也很理想,雖然 – Sherlock

2

假設uow.GetEntities<User>()回報IQueryable<User>,當有用戶從列表中的ID,所提出的解決方案涉及執行兩個昂貴IN (...) SQL查詢,還建設並傳遞ids列表兩次到數據庫 - 一個用於Any,一個用於Where

我寧願採用不同的結構。我會根據ids.Contains執行Where的查詢,並將結果存入內存中。然後我會在本地檢查它是否包含數據,如果是,將返回結果,否則,其他人將執行第二個查詢而不使用過濾器,這應該更有效。

事情是這樣的:

public List<User> getUsers (List<int> ids)   
{ 
    using(var uow = _repository.CreateUnitOfWork()) 
    {    
     var allUsers = uow.GetEntities<User>(); 
     var matchingUsers = allUsers 
      .Where(user => ids.Contains(user.Id)) 
      .ToList(); 
     return matchingUsers.Any() ? matchingUsers : allUsers.ToList(); 
    } 
} 

總括來說,你不能做你想用一個單獨的數據庫查詢什麼。它需要至少執行兩個查詢,唯一的問題是使用最有效的方法。

1

一個簡單的方法是使用Join

public List<User> getUsers (List<int> ids)   
{ 
    using(var uow = _repository.CreateUnitOfWork()) 
    {    
     var u = uow.GetEntities<User>() 
         .Join(ids,x=>x.Id,y=>y,(x,y)=>x).ToList(); 
     if (u.Count==0) 
       return uow.GetEntities<User>().ToList() 
     return u;   
    } 
} 
0
public IList<User> getUsers (List<int > ids = null) 
{      
     var query = _repository.GetEntities<User>(); 

     if (ids == null)     
      return query.ToList();     

     if (ids.Count()==1) 
     {      
      var singleUser = query.FirstOrDefault(user => ids.Contains(user.Id)); 
      if (singleUser!= null)          
       return new List<User>{ singleUser; };   

      return new List<User>();     
     } 

     return query.Where(user => ids.Contains(user.Id)).ToList();              
}