PetaPoco не может вставить запись с первичным ключом Guid newid

Я экспериментирую с Peta POCO ORM, и мне это очень нравится, однако есть одна вещь, которую я не могу заставить работать. Я использую MS SQL и таблицу с уникальным идентификатором в качестве первичного ключа. Однако, когда я вставляю новую запись, 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)
)

а затем в С# у меня есть:

[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);
                }
            }
}

Спасибо за любую помощь


person Biggles    schedule 04.04.2014    source источник


Ответы (3)


Я считаю, что вам нужно предварительно заполнить первичный ключ типа guid перед вызовом Insert. PetaPoco (по крайней мере, в V4) поддерживает автоматическое заполнение столбцов идентификации после вставки. Для столбцов guid вам нужно сгенерировать guid самостоятельно, вызвав Guid.NewGuid.

Это не «ограничение» PetaPoco. SQL Server хранит в памяти последнее сгенерированное значение идентификатора, которое можно получить сразу после INSERT с помощью SCOPE_IDENTITY(), @@IDENTITY или CHECK_IDENT (в зависимости от требуемой области действия). Нет ничего похожего на захват последнего сгенерированного значения GUID. Если вы используете GUID, вам придется создать собственный механизм для захвата последнего вставленного значения (т. е. получить GUID перед вставкой.

person Shital Shah    schedule 04.04.2014
comment
Вот как я это решил (ну, обошел), но я нахожу это довольно неуклюжим, так как GUID заполняется в MS SQL - person Biggles; 04.04.2014
comment
Как бы неуклюже это ни было, это стандартный способ, даже если вы не использовали PetaPoco. Обновил мой ответ. - person Shital Shah; 04.04.2014

Я столкнулся с той же проблемой, пытаясь вставить в таблицу с Guid PK. К сожалению, одного отмеченного ответа было недостаточно, чтобы решить мою проблему.

Мое решение состояло в том, чтобы сделать, как указано выше, установить идентификатор вручную с помощью Guid.NewGuid(), но также использовать следующий синтаксис для вставки. важным битом является автоматическое увеличение.

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

Эти аргументы сопоставляются с: table_name, pk_column_name, use_auto_increment, object

person StueyKent    schedule 01.10.2016
comment
Я действительно просто хочу сказать спасибо за публикацию этого. - person markau; 01.03.2017

Это тоже был мой вопрос, но я не мог найти ответ нигде. Итак, я нашел его для себя. На самом деле это ограничение 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())")); 

«DefaultSetting» — это значение по умолчанию, которое вы устанавливаете в базе данных для столбца. Для Guid это может быть newsequentialid() или newid(), решать вам.

person Thang Nguyen    schedule 14.07.2016