2011-03-03 55 views
4

想知道這是否是最有效的方法?有沒有一種方法可以在一個語句中使用所有的linq而不是調用方法,比如子查詢或其他?從linq語句中調用函數

newEmployee = (from emp 
       in db.employees 
       select new 
       { 
        a.EmployeeID, 
        a.Username, 
        Status = emp.GetEmployeeCurrentStatus(a.Username) 
       }).ToList(); 

這是它返回僱員的狀態GetEmployeeCurrentStatus:

public string GetEmployeeCurrentStatus(string username) 
     { 
      using (Entities db = new Entities()) 
      { 
       var times = (from d in db.TimeTables 
          where d.DateTime == DateTime.Today && 
          d.Employee.Username == username 
          select d) 
          .OrderByDescending(d => d.TimeID).FirstOrDefault(); 

       return (x.ClockOut == null ? "IN" : "OUT");         
      } 
     } 
+0

用戶 - 我無法看到該方法是如何工作的。 x.clockout從哪裏來?應該是times.clockout? – 2011-03-03 14:19:20

+0

是的,對不起,我的錯誤 – scouserider 2011-03-03 14:27:27

回答

3

怎麼樣:

newEmployee = (db.employees.Select(emp => new 
        { 
         emp.EmployeeID, 
         emp.Username, 
         Status = db.TimeTables 
         .Where(d => d.Employee.Username == emp.Username 
          && d.DateTime == DateTime.Today) 
          .Select(x => x.ClockOut == null ? "IN" : "OUT") 
          .FirstOrDefault() 
        })).ToList(); 

你嘗試可能出現更清潔,在功能上是好的。但是,它正在啓動一個二級數​​據庫調用。這對於可伸縮性和性能來說是不利的。我發佈的版本使用相同的初始數據庫連接,並將進行連接1-1。這將導致更緊密,更快的查詢以及更低的資源使用率。

0

不管效率的,具有GetEmployeeCurrentStatus(...)爲方法使得代碼更清晰,更可重複使用的。

+0

是的,但不是它打兩個電話到數據庫? – scouserider 2011-03-03 14:28:36

2

您無法真正在查詢中調用自定義方法(或將使用數據庫執行的查詢的一部分)。你有兩個基本的選擇:執行需要調用的方法select

  • 呼叫ToList(這種方式,該方法將在內存中調用數據)

  • 撰寫查詢,使得如果可能的話,它們都可以在SQL服務器上運行。這可以使用predicate builder中的AsExpandable擴展來完成。有關這是如何工作的更多信息,另請參閱my blog post

1

它適用於小數據(員工數)的罰款,但由於每個GetEmployeeCurrentStatus需要SQL新連接,所以它不是最佳實踐。 我個人會得到所有員工(一次旅行數據庫),然後讓所有的員工狀態(一次旅行數據庫),所以我兌現了他們,我現在就加入他們本地

希望這有助於

0

假設您正在使用LINQ to SQL或EF,我會重構您的查詢以使用Join。這樣,您將在數據庫上執行一個高效的SQL查詢,而不是兩個單獨的查詢。