2011-05-29 155 views
0

我知道實體框架有一些LINQ支持問題(至少與其前身LINQ to SQL相比)......通常我可以找到重構我的LINQ查詢的創造性方式它支持EF並且不拋出一個實體框架複雜LINQ支持

"Unable to create a constant value of type ..." 

但是這次我遇到了麻煩。像往常一樣,這個問題與複雜的連接有關。這次我們需要對一些我正在使用的遺留數據進行建模。

我有辦事處查詢(一個簡單的POCO)

public IQueryable<Office> Offices 
{ 
    get 
    { 
     IQueryable<Office> query = 
      from pn in _context.Locations 
      where pn.Type == "Y" 
      select new Office 
      { 
       Id = pn.Id + 1000, 
       Name = pn.Name, 
      }; 

     query = query.Union(
      from r in _context.Resources 
      where r.ResourceType == "L" 
      select new Office 
      { 
       Id = r.ResourceId, 
       Name = r.ResourceName, 
      }); 

     return query; 
    } 
} 

然後,我有別的東西上有一個寫字樓物業。

public IQueryable<ScheduleEntry> ScheduleEntries 
{ 
    get 
    { 
     return 
      from pc in _context.CalendarEntries 
      join o in this.Offices on pc.LocationId 
       equals o.Id into offices 
      from office in offices.DefaultIfEmpty() 
      let mainOffice = this.Offices.First() 
      select new ScheduleEntry 
      { 
       Id = pc.CalendarId, 
       StartDateTime = pc.StartDateTime ?? DateTime.MinValue, 
       EndDateTime = pc.EndDateTime ?? DateTime.MinValue, 
       Office = pc.LocationId == 0 ? mainOffice : office, 
      }; 
    } 
} 

請注意,告訴我使它成爲一個枚舉失敗的目的......所以請不要提醒。

等等....做CalendarEntries.ToArray()拋出"Unable to create a constant value of type Office"...

具體問題是let mainOffice = Offices.First()。如果我刪除該邏輯,查詢工作正常。任何想法如何使這個工作與實體框架?

謝謝。

+2

哇。 「可憐的LINQ支持?」我認爲你應該把這個問題關閉的情緒或風險編輯爲主觀和論證。堅持這一點。 – 2011-05-29 01:35:35

+2

EF沒有差的linq支持。它不依賴於商店。 Linq to sql基本上是一個SQL Server代碼生成,而EF是一個真正的ORM。這意味着只有在任何數據存儲(不只是SQL Server)中有辦法執行它們時,計算的屬性纔會起作用。這不是不好的支持,只是通用的數據存儲支持。 – Gats 2011-05-29 01:42:18

+0

這聽起來更像是一個威脅,而不是一個建議。雖然公平,但我正在尋求幫助,而不是威脅。 – Jeff 2011-05-29 01:43:06

回答

2

好的,看起來像雙查詢是絆倒它。唯一的選擇是要麼離開加盟辦公室或執行以下操作:

 Office mainOffice = Offices.First(); 
     return from pc in _context.CalendarEntries 
       join o in Offices on pc.LocationId equals o.Id into offices 
       from office in offices.DefaultIfEmpty() 
       select new ScheduleEntry 
          { 
           Id = pc.CalendarId, 
           StartDateTime = pc.StartDateTime ?? DateTime.MinValue, 
           EndDateTime = pc.EndDateTime ?? DateTime.MinValue, 
           Office = pc.LocationId == 0 ? mainOffice : office, 
          }; 

我假設你不想做,由於對使它IEnumerable的投訴,所以你需要加入到辦事處可查詢一些如何告訴EF如何將查詢串起來。讓x = y或者value = value尋找一個我認爲有意義的常量。

+0

我得到相同的「無法創建類型...的常量值」異常。 – Jeff 2011-05-29 02:34:35

+0

看了更深,編輯的建議。對不起,我試圖回答自己的問題,並且陷入了這個問題:D – Gats 2011-05-29 02:44:44

+0

謝謝。我得到同樣的錯誤這樣做...但是,如果我得到的主要辦公室Id前期:var mainOfficeId = Offices.First()。Id,然後使用該ID在查詢中的第二個連接,它的工作....它是不理想,但它的工作原理。 – Jeff 2011-05-29 02:45:46

0

First在構建表達式樹時執行查詢,以便嘗試將Office作爲參數傳遞給您的查詢,但無法完成。

取代First的一種方法是呼叫this.Offices.Take(1)

+0

這也會產生相同的「無法創建常量值類型」錯誤。另外 - 如果表達式樹是大型表達式樹的一部分,則首先不執行查詢。也就是說,在我提供的原始示例中,它是作爲Method First的MethodCallExpression創建的......它不會在構建時直接執行。 – Jeff 2011-05-29 14:17:02

+0

@Jeff:我剛剛在另一個查詢上測試了First,並且一旦我在子查詢中使用它,我得到一個異常:*'First'方法只能用作最終的查詢操作。考慮在這個例子中使用方法'FirstOrDefault'。*所以我仍然認爲'First'不能在查詢中使用,但'FirstOrDefault'可以。 – 2011-05-29 14:23:12

+0

好點!...但這仍然是EF提供者的一個功能,而不是表達式樹的創建方式。我只是嘗試用FirstOrDefault()替換First()中的First(),我仍然得到相同的「無法創建常量值...」異常... – Jeff 2011-05-29 14:34:26