2012-04-17 59 views
1

我試圖在一個非常簡單的表上運行查詢,但我沒有得到任何結果。該表中包含的行爲日誌有以下欄目:linq動態查詢使用PredicateBuilder的實體

  • ID
  • ActionTypeID(創建,編輯或刪除)
  • 的EntryID(創建/編輯/或刪除條目的ID)
  • 表名(這裏的行動是堅定)
  • 控件名稱
  • 人(誰犯了行動。NT用戶與部門)
  • 日期

我想要得到的是ActionTypeID == 1和Person(department)以動態字符串之一結尾的所有EntryID的列表。問題是,只應檢查操作日誌中的一個EntryID的第一個操作以匹配其中一個部門。

我知道這聽起來很奇怪。這可能是由於我的英語不好,以及我的前同事設計殘疾的數據庫造成的。我不知道哪個更糟。

我試圖得到我想要的結果是這樣的:

var predicate = PredicateBuilder.False<ActionLog>(); 
var pOuter = PredicateBuilder.True<ActionLog>(); 

pOuter = pOuter.And(h => h.TableName.ToUpper() == "Contact".ToUpper()); 
pOuter = pOuter.And(h => h.ActionType.ID == 1); 

foreach (var dep in b.DepartmentList) 
{ 
    predicate = predicate.Or(x => x.Person.EndsWith("/" + dep.Value)); 
} 

pOuter = pOuter.And(predicate.Expand()); 

mContactIDs = (from h in db.ActionLog 
orderby h.Date 
select h).AsExpandable().Where(pOuter).Select(x => x.EntryID).Distinct().ToList(); 

但這返回我當「人」與選定的部門結尾的所有條目。我只想用這個EntryID檢查第一個條目。

我希望任何人都能理解我想從困惑的德語翻譯成奇怪的英語。

OH-順便說一下,它的.Net 3.5

編輯 我覺得我有一些問題找到合適的解釋 - 我會用一些虛擬數據試試。

ID | ActionTypeID | EntryID | TableName | ControlName | Person    | Date 
---------------------------------------------------------------------------------------- 
1 | 1   | 3  | 'Contacts' | NULL  | 'xxxx/department1' | 04/11/2012 
2 | 1   | 3  | 'Contacts' | NULL  | 'yyyy/department2' | 04/11/2012 
3 | 1   | 5  | 'Contacts' | NULL  | 'yyyy/department2' | 04/13/2012 
4 | 1   | 14  | 'Contacts' | NULL  | 'zzzz/department1' | 04/16/2012 

在我的例子,我將搜索與日誌條目「人用‘/ department2’結束創建了一個新的EntryID中第一次出現」,「表名==‘聯繫人’」和「ActionTypeID == 1 」。我想要接收的結果是(僅限EntryIDs)5,因爲這是唯一的入口,其中department2的用戶是第一個插入此ActionID的ActionTypeID 1.我知道這很愚蠢,如果我設計了數據庫I不會這樣做,但現在我必須處理它。如果部門查詢的數量不會是動態的,我會用這個片段:

IQueryable<ActionLog> log = db.ActionLog; 
mContactIDs = (from k in db.Contacts 
    where (from h in log 
     where h.TableName == "Contacts" 
     && h.EntryID == k.ID 
     && h.ActionType.ID == 1 
     orderby h.Date 
     select h).FirstOrDefault().Person.EndsWith("/" + b.Department) 
    select k.ID).ToList(); 

但我不知道如何將這些動態部門與愚蠢的設計(和多ActionTypeID 1(創建)連接爲一個我甚至不知道爲什麼應用程序會保存這個)

謝謝,本。

回答

0

我決定改用實體SQL。

 List<int> mContactIDs = new List<int>(); 
     using (var db = new Entities()) 
     { 
      string queryString = @" 
           SELECT 
            VALUE H.EntryID 
           FROM  
            Entities.ActionLog AS H 
           WHERE 
            H.ID IN (
             SELECT VALUE TOP (1) Hi.ID 
             FROM Entities.ActionLog AS Hi 
             WHERE Hi.ActionType.ID = 1 
             AND Hi.TableName = 'Kontakt' 
             AND Hi.EntryID = H.EntryID 
             ORDER BY Hi.Date  
            ) 
           {0} 
           GROUP BY H.EntryID"; 

      List<string> lDepartments = new List<string>(); 
      foreach (var dep in b.DepartmentList) 
      { 
       lDepartments.Add(string.Format(" H.Person LIKE '%{0}' ", dep.Value)); 
      } 

      string sDepartmentQuery = string.Empty; 
      if (lDepartments.Count > 0) 
      { 
       sDepartmentQuery = string.Format(" AND ({0}) ", string.Join(" OR ", lDepartments.ToArray())); 
      } 

      var result = db.CreateQuery<int>(string.Format(queryString, sDepartmentQuery)); 
      if (result != null && result.Count() > 0) 
      { 
       mContactIDs = result.ToList(); 
      } 
     } 
+0

我沒有寫_that_ :-) – Ben 2012-04-24 12:20:05

0

我認爲問題是在foreach循環內捕獲的變量值(即dep.Value)。複製變量並在表達式中使用它。該問題解釋爲here

foreach (var dep in b.DepartmentList) 
{ 
    var depValue = dep.Value; 
    predicate = predicate.Or(x => x.Person.EndsWith("/" + depValue)); 
} 
+0

嗨,謝謝你的回答。這是我沒有想到的問題 - 謝謝。但我認爲我的主要問題是合乎邏輯的。我想我沒有很好地解釋它。我會用一些虛擬數據嘗試它(我會編輯我的問題) – Ben 2012-04-17 04:31:36