2012-06-27 44 views
0

幾天前我把question關於使用EF映射兩個類MessageMessageStatusHistory。映射進行得很好,但我正面臨Message類中的導航屬性StatusHistoryMessageStatusHistory對象有關的一些問題。我只爲一個用戶加載消息,並只想要與該用戶有關的狀態。就像我想要顯示的,如果用戶已標記爲已讀/未讀和何時。如果我使用默認加載機制類似以下加載所有用戶的相關信息,不論歷史:使用Entity Framework 4.3的過濾器加載導航屬性

IDbSet<Message> dbs = _repo.DbSet; 
dbs.Include("StatusHistory").Where(x=>x.MessageIdentifier == msgIdentifier); 

要過濾的歷史對於一個用戶只有我嘗試以下竅門:

IDbSet<Message> dbs = _repo.DbSet; 
var q = from m in dbs.Include("StatusHistory") 
     where m.MessageIdentifier == msgIdentifier 
     select new Message 
     { 
      MessageIdentifier = m.MessageIdentifier, 
      /*OTHER PROPERTIES*/ 
      StatusHistory = m.StatusHistory 
          .Where(x => x.UserId == userId).ToList() 
     }; 

return q.ToList();//THROWING ERROR ON THIS LINE 

我得到的錯誤:

The entity or complex type 'MyLib.Biz.Message' cannot be constructed in a LINQ 
to Entities query. 

我也試過通過評論StatusHistory = m.StatusHistory.Where(x => x.UserId == userId).ToList()也但沒有幫助。

請幫助我通過過濾StatusHistory獲取消息。

編輯: -上述解決與此代碼:

var q = from m in _repository.DBSet.Include("Histories") 
     where m.MessageIdentifier == id 
     select new { 
        m.Id,/*OTHER PROPERTIES*/ 
        Histories = m.Histories.Where(x => 
            x.SenderId == userId).ToList() 
        }; 

var lst = q.ToList(); 
return lst.Select(m => new Message{ 
      Id = m.Id, MessageIdentifier = m.MessageIdentifier, 
      MessageText = m.MessageText, Replies = m.Replies, 
      ReplyTo = m.ReplyTo, Histories = m.Histories, SenderId = 
      m.SenderId, SenderName = m.SenderName, CreatedOn = m.CreatedOn 
     }).ToList(); 

但如果我嘗試以包括與回覆消息:

from m in _repository.DBSet.Include("Replies").Include("Histories") 

我收到錯誤的轉換查詢用q.ToList()Histories = m.Histories.Where(x=> x.SenderId == userId).ToList()一起列出。

+1

這不是StatusHistory。查看例外情況:您無法在實體查詢中創建實體對象。您必須創建鏡像類型或匿名類型。 –

回答

0

關於您的編輯部分:您不能在投影中使用ToList(),只需將其保留爲IEnumerable<T>,並在構建Message時將其轉換爲List<T>。你也不需要創建兩個目錄對象,可以從LINQ切換到實體查詢LINQ到對象(第二Select)通過使用AsEnumerable()

var list = (from m in _repository.DBSet 
      where m.MessageIdentifier == id 
      select new { 
       // ... 
       Histories = m.Histories.Where(x => x.SenderId == userId) 
      }) 
      .AsEnumerable() // database query is executed here 
      .Select(m => new Message { 
       // ... 
       Histories = m.Histories.ToList(), 
       // ... 
      }).ToList(); 

return list; 

注意Include沒有效果,當你與select一起使用投影。您需要創建您想要包含投影的一部分的屬性 - 就像您已經使用select new { Histories....一樣。

+0

感謝您的幫助。只是一個小問題:爲什麼'm.Histories.Where(x => x.SenderId == userId).ToList()'工作,如果我只有'.Include(「歷史」)'而不是當我有'。在查詢中包含(「回覆」)? – TheVillageIdiot

+1

@ TheVillageIdiot:你確定第二個'Include'有效嗎?老實說,在投影中使用'ToList()'永遠不會工作,不管你是否有'Include'和多少個。它應該總是把臭名昭着的「......不能將'ToList'轉換成商店表達...」的例外。 – Slauma

+0

是的,你是對的。它也在那裏拋出異常。我誤解了另一種方法(使用'ToList')。 – TheVillageIdiot

相關問題