PetaPoco无法使用Guid newid主键插入记录

时间:2014-04-04 08:21:58

标签: c# sql-server petapoco

我正在尝试使用Peta POCO ORM而我非常喜欢它,但有一件事我无法工作。我使用MS SQL和带uniqueidentifier的表作为主键。但是,当我插入新记录时,POCO会抛出一个InvalidCastException,试图将DBNull强制转换为Guid。我创造了一个简单的例子。 MS SQL表定义:

    CREATE TABLE MyTable
(
    id uniqueidentifier NOT NULL DEFAULT newid(),
    name nvarchar(50) NULL,
    surname nvarchar(50) NULL,
    CONSTRAINT pk_MyTable PRIMARY KEY (id)
)

然后在C#中我有:

[PetaPoco.TableName("MyTable")]
[PetaPoco.PrimaryKey("id")]
public class MyTable
{
    public Guid id { get; set; }
    public string name { get; set; }
    public string surname { get; set; }
}

最后我尝试插入新记录:

using (var conn = new SqlConnection(myConnString))
{
conn.Open()
using (var db = new PetaPoco.Database(conn))
            {
                for (int i = 0; i < 3; i++)
                {
                    var table = new MyTable() { name = "oh my", surname = i.ToString() };
                    db.Insert(table);
                }
            }
}

感谢您的帮助

3 个答案:

答案 0 :(得分:5)

我遇到了同样的问题,试图插入带有Guid PK的表格。不幸的是,单独的明确答案还不足以解决我的问题。

我的解决方案是如上所述,使用Guid.NewGuid()手动设置Id,但也使用以下语法进行插入。重要的是自动增量。

db.Insert("MyTable", "id", false, table);

这些参数映射到: table_name,pk_column_name,use_auto_increment,object

答案 1 :(得分:2)

我相信你需要在调用Insert之前预先填充guid类型的主键。 PetaPoco(至少在V4中)支持插入后自动填充标识列。对于guid列,您需要通过调用Guid.NewGuid自己生成guid。

这不是PetaPoco&#34;限制&#34;。 SQL Server将最后生成的标识值保留在内存中,可以使用SCOPE_IDENTITY(),@@ IDENTITY或CHECK_IDENT(取决于您需要的范围)在INSERT之后立即检索。没有类似的东西捕获最后生成的GUID值。如果您使用GUID,则必须创建自己的机制来捕获最后插入的值(即在插入之前检索GUID。

答案 2 :(得分:1)

这也是我的问题,但我无法在任何地方找到答案。所以,我为自己找到了它。实际上,这是petapoco的限制,因为它不会检查Guid键的自动增量。

让我们在文件PetaPoco.Core.ttinclude中找到以下一行:

col.IsAutoIncrement=((int)rdr["IsIdentity"])==1 //This is only check for integer key.

修复:

col.IsAutoIncrement=((int)rdr["IsIdentity"])==1 || 
                        (!DBNull.Value.Equals(rdr["DefaultSetting"]) && ((string)rdr["DefaultSetting"] == "(newsequentialid())" ||
                        (string)rdr["DefaultSetting"] == "(newid())")); 

&#34; DefaultSetting&#34;是您在数据库中为列设置的默认值。对于Guid,它可能是newsequentialid()或newid(),它取决于你。