为什么 PetaPoco 从 db.Insert ID 字段返回 7 作为十进制

发布于 2024-11-14 01:42:40 字数 295 浏览 4 评论 0原文

当执行插入时,变量 id 作为对象返回。然而,在我的数据库中它是一个 int,在我的 POCO 中它是一个 int,但是当调用 ExecuteScalar 返回 @@IDENTITY 的方法时,它返回数字 7 作为对象,但调试器认为它是十进制。

因此,当我执行 int newID = (int)db.Insert(...) 时,它会抛出

InvalidCastException

Is this a Framework bug or a PetaPoco bug?

When doing a Insert the variable id is returned as an object. However in my database it is an int and in my POCO it is an int however when the method call to ExecuteScalar to return @@IDENTITY is called it returns the number 7 as an object but the debugger thinks its a decimal.

Therefore when I do int newID = (int)db.Insert(...) it throws a

InvalidCastException

Is this a framework bug or a PetaPoco bug?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

岁吢 2024-11-21 01:42:40

还要记住,如果您已经设置了班级并像这样插入。

[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 更改为新创建的身份值

Also remember that if you have set your class up and you insert like so.

[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 will now change from 0 to the newly created identity value

遇见了你 2024-11-21 01:42:40

这将取决于您要连接到的 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;
}

It's going to depend on what RDBMS you are connecting to, which you didn't state.

Here's the relevant code from PetaPoco that retrieves the last id and returns it:

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;
}
离笑几人歌 2024-11-21 01:42:40

另外两分钱。正如已经回答的那样,PetaPoco 返回 SQL Server 插入的小数。问题作者正在尝试转换为引发 InvalidCastException 的 int 。但是,类型转换确实有效。因此,不要这样做:

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

这样做:

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

Another two cents. As already answered PetaPoco returns a decimal for SQL Server Inserts. The question author is attemping to cast to an int which throws an InvalidCastException. However, a Type Conversion does work. So instead of this:

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

do this:

int newID = Convert.ToInt32(db.Insert(...))
一刻暧昧 2024-11-21 01:42:40

这是一个猜测,但值得一试。在 PetePoco.cs 中尝试将 : 更改

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

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

It's a guess but worth a go. In PetePoco.cs try changing :

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

to

id = ExecuteScalar<int>("SELECT @@@IDENTITY AS NewID;");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文