执行 Insert 时,变量 id 作为对象返回。但是在我的数据库中它是一个 int 而在我的 POCO 中它是一个 int 但是当调用 ExecuteScalar 以返回 @@IDENTITY 的方法调用时,它返回数字 7 作为一个对象,但调试器认为它是一个小数。
因此,当我这样做时,int newID = (int)db.Insert(...)
它会抛出一个
InvalidCastException
这是框架错误还是 PetaPoco 错误?
还要记住,如果你已经设置了你的类并且你像这样插入。
[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 更改为新创建的标识值
这将取决于您连接到的 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;
}
还有两分钱。正如已经回答的那样,PetaPoco 为 SQL Server 插入返回一个小数。问题作者正在尝试强制转换为引发 InvalidCastException 的 int。但是,类型转换确实有效。所以代替这个:
int newID = (int)db.Insert(...)
做这个:
int newID = Convert.ToInt32(db.Insert(...))
这是一个猜测,但值得一试。在 PetePoco.cs 中尝试更改:
id = ExecuteScalar<object>("SELECT @@@IDENTITY AS NewID;");
至
id = ExecuteScalar<int>("SELECT @@@IDENTITY AS NewID;");