2016-08-23 41 views
0

我在ASP.NET MVC 5中創建一個Web應用程序,並需要使用數據庫獲取一些數據。一旦獲得數據,我想創建一個使用它的IPagedList對象。但是,我發現這個功能會產生一個異常,說明Type CurrentSite is not supported in LINQ to Entities。相反,僅在獲取數據並且不創建IPagedList時纔會發生這種情況。如何在創建IPagedList時防止「LINQ to Entities不支持」異常?

public ActionResult GetComputers(int? SiteID) 
{ 
    //This works 
    IQueryable<Computer> computers = db.Computers.Where(c => c.CurrentSite.ID == SiteID); 

    //This doesn't - It throws the LINQ to Entities exception 
    IPagedList<Computer> computers = db.Computers.Where(c => c.CurrentSite.ID == SiteID).ToPagedList(1, 25); 
} 

如何創建使用所獲得的數據,而無需添加CurrentSite列到我的數據庫表中的IPagedList對象?

更新: 這是邏輯CurrentSite屬性的邏輯。

public ComputerSites CurrentDeployment 
{ 
    get 
    { 
     if (this.ComputerSites == null) 
     { 
      return null; 
     } 
     else 
     { 
      return this.ComputerSites.Where(cs => DateTime.Now.IsBetween(cs.StartDate, cs.EndDate) && cs.Deleted == false).OrderBy(cs => cs.StartDate).FirstOrDefault(); 
     } 
    } 
} 

public Site CurrentSite 
{ 
    get 
    { 
     if (this.CurrentDeployment == null) 
     { 
      return null; 
     } 
     else 
     { 
      return this.CurrentDeployment.Site; 
     } 
    } 
} 
+0

您的IPagedList從哪裏來? – TGlatzer

+0

'db.Computers.Where(c => c.CurrentSite.ID == SiteID).ToList();'工作嗎? –

+0

@AdilMammadov我只是試過這個,並得到相同的錯誤,即使在訂購查詢時。 – Ben

回答

0

PagedList使用SkipTake內部(source)。

public static IPagedList<T> ToPagedList<T>(this IEnumerable<T> superset, int pageNumber, int pageSize) 
{ 
    return new PagedList<T>(superset, pageNumber, pageSize); 
} 


public PagedList(IQueryable<T> superset, int pageNumber, int pageSize) 
{ 
    ................... 

    // add items to internal list 
    if (superset != null && TotalItemCount > 0) 
     Subset.AddRange(pageNumber == 1 
      ? superset.Skip(0).Take(pageSize).ToList() 
      : superset.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList() 
     ); 
} 

LINQ到實體Skip是在有序的查詢只支持。因此,您必須命令您的查詢使用IPagedList

IPagedList<Computer> computers = db.Computers 
    .Where(c => c.CurrentSite.ID == SiteID) 
    .OrderBy(c => c.CurrentSite.ID) // Or some other property. 
    .ToPagedList(1, 25); 

現在它應該按預期工作。

+0

我試着像在這個答案中那樣排序查詢,但是我仍然得到了同樣的異常,說明'CurrentSite'不被支持。 – Ben

+0

然後你的模型出了問題。你也應該提供你的模型。 –

0

IQueryable不會拋出異常,因爲您只是構建表達式而不執行它; Linq to Entities還沒有拋出異常,因爲它不知道它會觸發它。相反,當你使用IPagedList時,你正在評估這個表達式,這就是拋出異常的原因。

簡而言之,Linq理解原始類型,但不理解自己創建的複雜類型。雖然有幾個解決方法,但如果可以的話,它最好是封裝您正在綁定的邏輯,以在Where語句中的CurrentSite中引入。核心問題是,當你在一個屬性中有邏輯時,Linq無法將它編譯成SQL就緒代碼來在你的數據庫中進行交互。

-1

有時最簡單的解決方案是最有效的。事實證明,您可以通過向查詢添加AsEnumerable調用來繞過該問題,如此。

db.Computers.AsEnumerable().Where(c => c.CurrentSite.ID == SiteID).ToPagedList(1, 25); 

它現在正常工作。

+0

我做downvote,因爲你不明白調用AsEnumerable,它是獲取整個查詢的影響。 –

相關問題