各位先進好,小弟ASP.NET MVC + Lambda初心者,上來求教,可能會有很多用詞、標題與描述沒有那麼的到位或詳細,請各位見諒~
問題:
目前剛規劃一個新專案,寫好一個資料表MVC相關程式碼,在搜尋單一資料表Conference的功能測試沒問題,如下程式碼,將資料由DB撈出來並在View裡呈現,測試是沒問題的。
SubmissionEntities db = new SubmissionEntities();
private IQueryable<Conference> GetAllGetConferenceDataList(ForPaging Paging, string Search)
{
//根據搜尋值來搜尋資料
IQueryable<Conference> Data = db.Conferences.Where(c =>
//計算所需的總頁數
Paging.MaxPage = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(Data.Count()) / Paging.ItemNum));
Paging.testNum = Data.Count();
//Paging.MaxPage = 6;
//重新設定正確的頁數,避免有不正確值傳入
Paging.SetRightPage();
//回傳搜尋資料
return Data;
}
因為資料表關聯的問題,所以要修改以上程式碼,加入Join MemberToConferences資料表的判斷,修改如下:
SubmissionEntities db = new SubmissionEntities();
private IQueryable<Conference> GetAllGetConferenceDataList(ForPaging Paging, string Search)
{
//根據搜尋值來搜尋資料
IQueryable<Conference> Data = db.Conferences.Join(db.MemberToConferences,
c => c.ConferenceId,
mc => mc.ConferenceId,
(c, mc) => new
{
ConferenceId = c.ConferenceId,
ConferenceTitle = c.ConferenceTitle,
ConferenceLocation = c.ConferenceLocation,
ContactName = c.ContactName
}).OrderBy(c => c.ConferenceId).Where(c => c.ConferenceTitle.Contains(Search) || c.ConferenceLocation.Contains(Search) || c.ContactName.Contains(Search));
//計算所需的總頁數
Paging.MaxPage = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(Data.Count()) / Paging.ItemNum));
Paging.testNum = Data.Count();
//Paging.MaxPage = 6;
//重新設定正確的頁數,避免有不正確值傳入
Paging.SetRightPage();
//回傳搜尋資料
return Data;
}
VS就指出發生型別錯誤,應該是指以上程式碼撈出來的資料並非為IQueryable型態,需要轉型,目前我對Join其它資料表的程式撰寫不熟,所以不知道該如何修正以上這個需求,故上來請教。
採用DB First + EF + ViewModel方式開發,如有需要其它資訊我再補上,大感謝各位先進指教了,謝謝~
LINQ to Entities 查詢中無法建構實體或複雜類型 'SubmissionModel.Conference'。
描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。例外狀況詳細資訊: System.NotSupportedException: LINQ to Entities 查詢中無法建構實體或複雜類型 'SubmissionModel.Conference'。
麻煩看一下圖片,主要你在new Conference動作時,代表建立沒有資料庫效果的Conference物件
改成這樣就可以
LINQ to Entities 無法辨識方法 'Int32 ToInt32(System.Object)' 方法,而且這個方法無法轉譯成存放區運算式。
描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
LINQ 能跟資料庫互動是因為有解釋器轉成SQL
,對解釋器來說不認得ToInt32方法
所以我們可以改成LINQ一定認得的`『值』``,改寫成下面Code
var memberId = Convert.ToInt32(HttpContext.Current.Session["MemberId"];
IQueryable<Conference> Data = db.Conferences.Where(c => c.Enabled == true)
.Join(db.MemberToConferences.Where(mc => mc.MemberId == memberId)),
c => c.ConferenceId,
mc => mc.ConferenceId,
(c, mc) => c);
謝謝指正,我修改程式碼如下:
private IQueryable<Conference> GetAllGetConferenceDataList(ForPaging Paging)
{
//宣告要回傳的搜尋資料為資料庫中的Guestbooks資料表
//IQueryable<Conference> Data = db.Conferences.Where(c => c.Enabled == true);
IQueryable<Conference> Data = db.Conferences.Join(db.MemberToConferences.Where(mc => mc.MemberId == 5),
c => c.ConferenceId,
mc => mc.ConferenceId,
(c, mc) => new Conference
{
ConferenceId = c.ConferenceId,
ConferenceTitle = c.ConferenceTitle,
ConferenceLocation = c.ConferenceLocation,
ContactName = c.ContactName
})
.Where(c => c.Enabled == true);
//計算所需的總頁數
//Paging.MaxPage = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(Data.Count()) / Paging.ItemNum));
Paging.MaxPage = 6;
//重新設定正確的頁數,避免有不正確值傳入
Paging.SetRightPage();
//回傳搜尋資料
return Data;
}
接著遇到其它錯誤
LINQ to Entities 查詢中無法建構實體或複雜類型 'SubmissionModel.Conference'。
描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外狀況詳細資訊: System.NotSupportedException: LINQ to Entities 查詢中無法建構實體或複雜類型 'SubmissionModel.Conference'。
原始程式錯誤:
行 89:
行 90: //計算所需的總頁數
行 91: Paging.MaxPage = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(Data.Count()) / Paging.ItemNum));
行 92: //Paging.MaxPage = 6;
行 93: //重新設定正確的頁數,避免有不正確值傳入
若把Paging.MaxPage = 6;寫死試著跳過此錯誤,到呼叫此方法的函式還是再報類似的錯誤,程式碼及錯誤如下:
呼叫GetAllGetConferenceDataList(Paging)的主函式
public List<Conference> GetConferenceDataList(ForPaging Paging, string Search)
{
//宣告要接受全部搜尋資料的物件
IQueryable<Conference> SearchData;
//判斷搜尋是否為空或Null,用於決定要呼叫取得搜尋資料
if (String.IsNullOrEmpty(Search))
{
SearchData = GetAllGetConferenceDataList(Paging);
}
else
{
SearchData = GetAllGetConferenceDataList(Paging, Search);
}
//先排序再根據分頁來回傳所需部份的資料陣列
return SearchData.OrderByDescending(c => c.ConferenceId).Skip((Paging.NowPage - 1) * Paging.ItemNum).Take(Paging.ItemNum).ToList();
}
以下依然報錯
LINQ to Entities 查詢中無法建構實體或複雜類型 'SubmissionModel.Conference'。
描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外狀況詳細資訊: System.NotSupportedException: LINQ to Entities 查詢中無法建構實體或複雜類型 'SubmissionModel.Conference'。
原始程式錯誤:
行 44: }
行 45: //先排序再根據分頁來回傳所需部份的資料陣列
行 46: return SearchData.OrderByDescending(c => c.ConferenceId).Skip((Paging.NowPage - 1) * Paging.ItemNum).Take(Paging.ItemNum).ToList();
行 47: }
行 48: //包含搜尋值的搜尋資料方法
現在不懂的是,以下A,B兩個寫法回傳都是同樣型別,為何A可以順利執行,B卻無法呢?
A寫法
IQueryable<Conference> Data = db.Conferences.Where(c => c.Enabled == true);
B寫法,加入Join
IQueryable<Conference> Data = db.Conferences.Join(db.MemberToConferences.Where(mc => mc.MemberId == 5),
c => c.ConferenceId,
mc => mc.ConferenceId,
(c, mc) => new Conference
{
ConferenceId = c.ConferenceId,
ConferenceTitle = c.ConferenceTitle,
ConferenceLocation = c.ConferenceLocation,
ContactName = c.ContactName
})
.Where(c => c.Enabled == true);
還是卡關,不知道該如何修正,如果有先進看到問題,再麻煩指正了,謝謝~
感謝暐翰的指教,謝謝
測試回覆,我將搜尋寫法改成如下LINQ語法,程式就可以正常執行了,但還是不知道問題在那裡!
IQueryable<Conference> Data =
(from c in db.Conferences
join mc in db.MemberToConferences on c.ConferenceId equals mc.ConferenceId
where c.Enabled == true
select c);
雖然暫時解決問題可持續開發下去,但還是想知道上述造成問題的原因為何,如果有任何先進知道問題的還請麻煩指教一下了,大大感謝~
_
leo226 我更新回答在內文 你看一下
暐翰抱歉沒有注意上面有回文,感謝指教,依建議修改程式碼可正常運作~
想要再進一步請教延伸問題,搜尋條件想要再進一步帶入Session值為搜尋條件,修改成以下程式碼:
IQueryable<Conference> Data = db.Conferences.Where(c => c.Enabled == true)
.Join(db.MemberToConferences.Where(mc => mc.MemberId == Convert.ToInt32(HttpContext.Current.Session["MemberId"])),
c => c.ConferenceId,
mc => mc.ConferenceId,
(c, mc) => c);
執行階段出現以下錯誤訊息,我想應該是Session值引用錯誤的問題造成,因為若將Session值改為固定值帶入則可正常運作。
LINQ to Entities 無法辨識方法 'Int32 ToInt32(System.Object)' 方法,而且這個方法無法轉譯成存放區運算式。
描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外狀況詳細資訊: System.NotSupportedException: LINQ to Entities 無法辨識方法 'Int32 ToInt32(System.Object)' 方法,而且這個方法無法轉譯成存放區運算式。
原始程式錯誤:
行 90:
行 91: //計算所需的總頁數
行 92: Paging.MaxPage = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(Data.Count()) / Paging.ItemNum));
行 93: //Paging.MaxPage = 6;
行 94: //重新設定正確的頁數,避免有不正確值傳入
此Session["MemberId"]在View裡都可以正常的代出數值顯示,可是用在此搜尋類別檔裡卻會造成問題!
所以問題應該是我們應該如何在類別檔裡代入Session值使用呢?
不好意思,初心者遇到的問題有點多~謝謝幫忙~
leo226 我更新回答了
暐翰觀念清楚許多,感謝不吝指教,謝謝~