2013-07-30 37 views
1

錯誤:傳遞到字典中的模型項是類型'System.Data.Entity.Infrastructure.DbQuery(snip)...尋找類型'Advocate 「MVC4 linq查詢到對象不會作爲正確的對象出來

控制器的方法是這樣的:

[HttpGet] 
public ActionResult AdvocateEdit(int id) 
{ 
    var advocate = from a in db.Query<Advocate>().Include(a => a.AdvocateId) 
        where (a.AdvocateId == id) 
        select a; 

    return View(advocate); 
} 

的觀點確實輸入到倡導@model和步進通過後,我敢肯定,問題是這樣的查詢。它返回時需要是Advocate類型的。

db.Query is an IQueryable<T> method in my DbContext that returns Set<T>(). 

讓我知道是否需要更多信息。由於人們

ADDED ----

DbContext.cs

public interface IAcmeDb : IDisposable 
{ 
    IQueryable<T> Query<T>() where T : class; 
} 

public class AcmeDb : DbContext, IAcmeDb 
{ 
    public AcmeDb() : base("name=AcmeDB") {} 
    public DbSet<Advocate> Advocates { get; set; } 

    IQueryable<T> IAcmeDb.Query<T>() 
    { 
     return Set<T>(); 
    } 
} 

回答

3

如果您認爲需要一個Advocate而且永遠只有一個實體,對於一個給定的id,然後你想:

[HttpGet] 
public ActionResult AdvocateEdit(int id) 
{ 
    try 
    { 
     Advocate advocate = db.Query<Advocate>().Single(a => a.AdvocateId == id); 
     return View(advocate); 
    } 
    catch(InvalidOperationException ex) 
    { 
     //handle the case where no entity matches the supplied id (return status code 404?), or 
     //there are no Advocates at all (redirect to a create page?), or 
     //more than one entity matches (return status code 500) 
    } 
} 
2

至少有一個顯着的問題。 LINQ傾向於使用延遲執行。我的代碼中沒有看到你迫使查詢執行。除非View(advocate)中的某處列舉了查詢產生的IEnumberable<T>,否則您將不會處理Advocate類型的對象。

我會建議增加一個ToList()ToArray()調用到您的查詢結束,這將確保它實際上得到執行。如果這不起作用,我會打破查詢分開,並確保db.Query<Advocate>()返回你所期望的。

List<Advocate> = db.Query<Advocate>().Include(a => a.AdvocateId) 
        .Where(a.AdvocateId == id) 
        .Select(a => a).ToList(); 

我已經將您的查詢轉換爲方法語法,因爲它對我來說很熟悉。上面的例子可能會解決你的問題。我認爲要保持查詢語法,你應該把整個左手放在父母身上,然後加上ToList()調用,但我不確定正確的語法是什麼。

編輯:基於其他評論問題不是延期執行,而是嘗試將集合傳遞給查找單個實例的方法。使用上述相同的代碼,您只需將ToList()更改爲FirstOrDefault(),並且您的代碼可以正常工作;

List<Advocate> = db.Query<Advocate>().Include(a => a.AdvocateId) 
         .Where(a.AdvocateId == id) 
         .Select(a => a).FirstOrDefault(); 

注:引用類型的默認值是null這當然可以,因爲你的問題,如果你沒有到位適當的檢查無效。

+0

起初我只是用db.Advocates.Find(ID)和剛工作很好,但我不得不去看看並設置一個數據庫接口,以便我可以對假數據庫進行單元測試。應該可能只是切換一切,所以我可以繼續前進 –

+0

但是你的代碼仍然是Advocate的集合而不是Advocate,所以它不會修復錯誤。另外,即使視圖確實需要一個集合,通常也不需要在控制器中實現查詢。如果視圖需要實體,它將枚舉查詢。如果它不需要它們,那麼在控制器中執行查詢是很浪費的。也許該視圖將應用進一步的過濾器或其他東西,在這種情況下,您的方法將獲得超過必要的實體數量, –

+0

@MikeGoodwin好點。我忽視了他的觀點是尋找一個單身人士的事實。 – evanmcdonnal

4

我想你想傳遞一個Advocate元素給視圖,而不是查詢本身。試試這個:

return View(advocate.First()); 

倡導者對象在你的代碼的類型是IQueryable的,如果你的觀點預計的倡導對象,只得到查詢的第一個元素首先()或FirstOrDefault()。

+0

返回的斷點有'倡導者'類型爲System.Data.Entity.Infrastructure.DbQuery 。 advocate.First()拋出無效操作{「指定的Include路徑無效,EntityType'Acme.Web.Models.Advocate'沒有聲明名爲'AdvocateId'的導航屬性。」} –

+1

你在嘗試什麼包括(a => a.AdvocateId)?,我不認爲你需要這樣做。 – fcuesta

+0

只是試圖抓住一個特定的記錄......一直在做低水平的Windows服務編程一段時間,所以我的LINQ很生鏽。 –