2011-06-07 121 views
2

當執行Insert時,變量id作爲對象返回。然而,在我的數據庫中它是一個int,在我的POCO中它是一個int,但是當調用ExecuteScalar返回@@ IDENTITY的方法被調用時,它將數字7作爲對象返回,但調試器認爲它是小數。PetaPoco爲什麼從db返回。插入一個ID爲7的ID字段作爲十進制

所以當我做int newID = (int)db.Insert(...)它拋出一個

InvalidCastException 

這是一個框架的bug或PetaPoco錯誤?

+1

似乎不可思議。什麼是database.LastSql設置爲在崩潰之前? – 2011-06-07 22:02:03

+0

您的標識列是小數點嗎?如果是這樣,也許PetaPoco需要將ExecuteScalar結果轉換爲(int):http://stackoverflow.com/questions/2601620/why-does-select-scope-identity-return-a-decimal-instead-of-an-integer – 2011-06-07 22:08:26

回答

4

這將取決於您連接到的什麼RDBMS,您沒有聲明。

下面是PetaPoco檢索的最後一個ID,並返回其相關代碼:

object id; 
switch (_dbType) 
{ 
    case DBType.SqlServerCE: 
     DoPreExecute(cmd); 
     cmd.ExecuteNonQuery(); 
     id = ExecuteScalar<object>("SELECT @@@IDENTITY AS NewID;"); 
     break; 
    case DBType.SqlServer: 
     cmd.CommandText += ";\nSELECT SCOPE_IDENTITY() AS NewID;"; 
     DoPreExecute(cmd); 
     id = cmd.ExecuteScalar(); 
     break; 
    case DBType.PostgreSQL: 
     if (primaryKeyName != null) 
     { 
      cmd.CommandText += string.Format("returning {0} as NewID", EscapeSqlIdentifier(primaryKeyName)); 
      DoPreExecute(cmd); 
      id = cmd.ExecuteScalar(); 
     } 
     else 
     { 
      id = -1; 
      DoPreExecute(cmd); 
      cmd.ExecuteNonQuery(); 
     } 
     break; 
    case DBType.Oracle: 
     if (primaryKeyName != null) 
     { 
      cmd.CommandText += string.Format(" returning {0} into :newid", EscapeSqlIdentifier(primaryKeyName)); 
      var param = cmd.CreateParameter(); 
      param.ParameterName = ":newid"; 
      param.Value = DBNull.Value; 
      param.Direction = ParameterDirection.ReturnValue; 
      param.DbType = DbType.Int64; 
      cmd.Parameters.Add(param); 
      DoPreExecute(cmd); 
      cmd.ExecuteNonQuery(); 
      id = param.Value; 
     } 
     else 
     { 
      id = -1; 
      DoPreExecute(cmd); 
      cmd.ExecuteNonQuery(); 
     } 
     break; 
    default: 
     cmd.CommandText += ";\nSELECT @@IDENTITY AS NewID;"; 
     DoPreExecute(cmd); 
     id = cmd.ExecuteScalar(); 
     break; 
} 
+1

這是正確的。它確實取決於數據庫。即使你計算(*)是不同的數據庫,他們都返回不同的類型,一些整數,長整數,雙精度和小數。我會看看可以做些什麼來使它更統一。 – Schotime 2011-06-07 22:57:18

+0

我正在使用SQLCe – Jon 2011-06-08 08:43:30

+0

然後Gareth的答案應該適用於你,如果你不介意修改PetaPoco版本並且你的所有PK字段都是自動增量ID。 – 2011-06-08 15:02:18

1

這是一個猜測,但值得一去。在PetePoco.cs嘗試改變:

id = ExecuteScalar<object>("SELECT @@@IDENTITY AS NewID;"); 

id = ExecuteScalar<int>("SELECT @@@IDENTITY AS NewID;"); 
6

還要記住,如果你已經確立了自己的類並插入像這樣。

[TableName("Users")] 
[PrimaryKey("Id")] 
public class User { 
    public int Id {get;set;} 
    public string Name {get;set;} 
} 

var user = new User() { Name = "My Name" }; 
db.Insert(user); 
Assert.True(user.Id != 0); 

user.Id現在從0更改爲新創建的標識值

+0

這很好用!我不知道PetaPoco做到了這一點。 – guanome 2012-12-07 20:13:12

3

另兩分錢。正如已經回答PetaPoco爲SQL Server插入返回一個小數。問題作者正試圖將其轉換爲引發InvalidCastException的int。但是,類型轉換確實有效。因此,而不是這樣的:

int newID = (int)db.Insert(...) 

做到這一點:

int newID = Convert.ToInt32(db.Insert(...)) 
相關問題