問題:
若資料表裡不存在任何一筆資料,則程式執行錯誤,若資料表裡有資料,則程式執行成功
PaperAuthor pa = new PaperAuthor();
int AuthorId = db.PaperAuthors.Select(p => p.AuthorId).Max() + 1;
pa.AuthorId = AuthorId;
錯誤訊息如下
轉型為 'System.Int32' 型別失敗,因為具體化的值為 Null。此結果型別的泛型參數或此查詢,兩者中必須有一個使用可為 Null 的型別。
描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外狀況詳細資訊: System.InvalidOperationException: 轉型為 'System.Int32' 型別失敗,因為具體化的值為 Null。此結果型別的泛型參數或此查詢,兩者中必須有一個使用可為 Null 的型別。
原始程式錯誤:
行 93: {
行 94: PaperAuthor pa = new PaperAuthor();
行 95: int AuthorId = db.PaperAuthors.Select(p => p.AuthorId).Max() + 1;
行 96: pa.PaperId = PaperId;
行 97: pa.AuthorId = AuthorId;
知道是資料型別為Null造成的錯誤,可是試了幾個判斷Null方法再賦值的方式都失敗,想請教各位大師應該如何修正賦值比較OK呢?
感謝各位大師解惑了~謝謝
我的AuthorId是主鍵其中之一,所以是非null型態,因為當資料表是會新的狀況,或下WHERE條件下搜尋不到資料,那出來的的資料型別就為null,所以Convert.ToInt32就會錯誤。
找不資料情況下AuthorId為1版本:
var AuthorId = db.PaperAuthors
.Where(x => x.PaperId == PaperId)
.Select(p => p.AuthorId)
.DefaultIfEmpty(0)
.Max(id => (id + 1)) ;
上面邏輯相當於以下
var sql = "select isnull(max(AuthorId),0) + 1 from PaperAuthors where PaperId = @p0 ";
var AuthorId = db.Database.SqlQuery<int>(sql,PaperId);
另外看起來你想要模擬做出自增ID,建議不要這樣做,請使用資料庫本身的自增index
跟先進報告一下,我的AuthorId是主鍵其中之一,所以是非null型態,因為當資料表是會新的狀況,或下WHERE條件下搜尋不到資料,那出來的的資料型別就為null,所以Convert.ToInt32就會錯誤。
錯誤訊息如下
'/' 應用程式中發生伺服器錯誤。
轉型為 'System.Int32' 型別失敗,因為具體化的值為 Null。此結果型別的泛型參數或此查詢,兩者中必須有一個使用可為 Null 的型別。
描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外狀況詳細資訊: System.InvalidOperationException: 轉型為 'System.Int32' 型別失敗,因為具體化的值為 Null。此結果型別的泛型參數或此查詢,兩者中必須有一個使用可為 Null 的型別。
原始程式錯誤:
行 93: {
行 94: PaperAuthor pa = new PaperAuthor();
行 95: var maxAuthorId = Convert.ToInt32(db.PaperAuthors.Where(x => x.PaperId == PaperId).Select(p => p.AuthorId).Max());
行 96: //int AuthorId = db.PaperAuthors.Where(x => x.PaperId == PaperId).Select(p => p.AuthorId).Max() + 1;
行 97: int AuthorId = maxAuthorId + 1;
所以就是要如何判斷搜出來的值為null時,賦予AuthorId=1的寫法。
用以下的if判斷式也無法執行
if (maxAuthorId == null)
{
AuthorId = 1;
}
運算式的結果一律會是'false',因為類型int的值絕對不會等於類型int?的null
leo226 我更新回答在內文了
感謝前輩的指點,我確實是想要模擬做出自增ID的功能,因為覺得用DB本身的自增index編碼因資料刪刪減減,但編碼卻只能無限的往上遞增,所以才想做這個自增ID的功能,測試了一下前輩指點的方法,還是遇到了以下的錯誤,錯誤訊息如下:
'/' 應用程式中發生伺服器錯誤。
不支援具有型別 'System.Int32' 的輸入及型別 'System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' 的檢查的 'TypeAs' 運算式。LINQ to Entities 查詢中僅支援實體類型和複雜類型。
描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外狀況詳細資訊: System.NotSupportedException: 不支援具有型別 'System.Int32' 的輸入及型別 'System.Nullable`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' 的檢查的 'TypeAs' 運算式。LINQ to Entities 查詢中僅支援實體類型和複雜類型。
原始程式錯誤:
行 93: {
行 94: PaperAuthor pa = new PaperAuthor();
行 95: var AuthorId = db.PaperAuthors.Where(x => x.PaperId == PaperId).Select(p => p.AuthorId).Max(id => (id + 1) as int?) ?? 1;
行 96:
行 97: pa.PaperId = PaperId;
你要自己實做自增長id,你就需要考慮多人同時競爭存取資源(race)的問題,至少要鎖表(lock table),並且考慮到萬一產生的id重複,那要怎樣處理。
linq語法是一種程式語言中的程式語言,他會在materialize時經過編譯成sql來執行,同時也不完全等同於C#,不是所有C#型別跟處理這些型別的方法都能拿進去用的(因為實際執行的是SQL)。你不要在這裡做計算或轉型,而是把結果賦值給var xxx之後,判斷xxx是否是null再來處理比較好。
感謝各位先進指點,測試用暐翰前輩的方法,可順利執行。
雖然一開始想要做自增長id功能,但其實也沒有一定要這麼做,可以用DB本身的自增長Id功能替代。
只是想說都遇到問題了,也上來提問了,如果可以解決問題並上到一課,那是最好不過的了,所以感謝各位大大提供的建議,獲益良多,謝謝。
同意
跟先進報告一下,試著用Int32.TryParse來解決
PaperAuthor pa = new PaperAuthor();
var maxAuthorId = db.PaperAuthors.Where(x => x.PaperId == PaperId).Select(p => p.AuthorId).Max().ToString();
int AuthorId;
bool success = Int32.TryParse(maxAuthorId, out AuthorId);
if (!success)
{
AuthorId = 1;
}
else
{
AuthorId = Convert.ToInt32(maxAuthorId) + 1;
}
但在db.PaperAuthors.Where(x => x.PaperId == PaperId).Select(p => p.AuthorId).Max().ToString();
這一段就錯,錯誤訊息如下。
'/' 應用程式中發生伺服器錯誤。
轉型為 'System.Int32' 型別失敗,因為具體化的值為 Null。此結果型別的泛型參數或此查詢,兩者中必須有一個使用可為 Null 的型別。
描述: 在執行目前 Web 要求的過程中發生未處理的例外狀況。請檢閱堆疊追蹤以取得錯誤的詳細資訊,以及在程式碼中產生的位置。
例外狀況詳細資訊: System.InvalidOperationException: 轉型為 'System.Int32' 型別失敗,因為具體化的值為 Null。此結果型別的泛型參數或此查詢,兩者中必須有一個使用可為 Null 的型別。
原始程式錯誤:
行 93: {
行 94: PaperAuthor pa = new PaperAuthor();
行 95: var maxAuthorId = db.PaperAuthors.Where(x => x.PaperId == PaperId).Select(p => p.AuthorId).Max().ToString();
行 96: int AuthorId;
行 97: bool success = Int32.TryParse(maxAuthorId, out AuthorId);