2015-01-15 6 views
0

Я составил общий репозиторий для выполнения операций CRUD в проекте MVC.ServiceStack Ormlite Удалить не работает

Когда я пытаюсь удалить строку из таблицы с идентификатором на SQLServer, код, сгенерированный методом Ormlite Delete и проверенный с помощью профилировщика, не влияет на какие-либо строки.

Это операция Crud для удаления (очень простой):

public void Destroy<T>(T entity) 
    { 
     using (var db = dbFactory.Open()) 
     { 
      db.Delete<T>(entity); 
     } 
    } 

Тип T в моем тесте представлен следующий класс:

[Alias("FT_TEST_DEVELOPMENT")] 
public class TestTable 
{ 
    [AutoIncrement] 
    [PrimaryKey] 
    public int ID { get; set; } 
    public string DESCR { get; set; } 
    public DateTime? TIMESTAMP { get; set; } 
    public DateTime DATE { get; set; } 
    public decimal PRICE { get; set; } 
    public int? QTY { get; set; } 
} 

И осмотрены код соответствует следующее:

exec sp_executesql N'DELETE FROM "FT_TEST_DEVELOPMENT" WHERE "ID"[email protected] AND "DESCR"[email protected] AND "TIMESTAMP"[email protected] AND "DATE"[email protected] AND "PRICE"[email protected] AND "QTY"[email protected] ', 
       N'@ID int,@DESCR nvarchar(6),@TIMESTAMP datetime,@DATE datetime,@PRICE decimal(2,0),@QTY int', 
       @ID=4,@DESCR=N'SECOND',@TIMESTAMP=NULL,@DATE='2015-06-01 00:00:00',@PRICE=15,@QTY=NULL 

Когда я выполняю это совершенно разумное d, сервер говорит мне, что ни одна строка

Отказ от ответственности: как некоторые имена, где на моем родном языке я перевел их, чтобы могла быть небольшая ошибка грамматики, если это так, позвольте мне заметить, и я отредактирую.

ОБНОВЛЕНИЕ

Совпадение строка фактически существует в базе данных

SELECT * FROM FT_TEST_DEVELOPMENT WHERE ID = 4 ID DESCR ТШЕЗТАМР ДАТА ЦЕНА КОЛ 4 ВТОРОЙ NULL, NULL, 2015-06-01 15

Я имею в виду, что на самом деле сгенерированный код OrmLite выглядит прослушивающим.

И да, столбец ID - это ключ таблицы.

ВТОРАЯ UPDATE Я думаю, что я нашел причину:

на самом деле в предложении WHERE Нулевые поля присваиваются в пути

@TIMESTAMP=NULL 

, но на самом деле сервер SQL не будет соответствовать это заявление, поскольку оно ожидает получить

WHERE [...] AND "TIMESTAMP" IS NULL [...] 
+1

Вы определили «ID» в качестве первичного ключа в таблице или это просто «ИДЕНТИФИКАЦИЯ»? 'IDENTITY' не указывает поле в качестве первичного ключа –

+0

Kalispera! Я также пробовал с ** ** [PrimaryKey] ** атрибутом, но ничего не изменилось, так или иначе я отредактирую вопрос, THX – Pizzaboy

+1

Вам нужно поставить [PrimaryKey] там * и * убедитесь, что ID является первичным ключом на Таблица. Кроме того, я подозреваю, что 'db.Delete ()' является опечаткой, и вы имели в виду 'db.Delete (entity)'. Все это должно изменить предложение 'WHERE' оператора, чтобы проверить только поле ID. Также убедитесь, что есть * строки *, которые соответствуют критериям –

ответ

2

Путь db.Delete() API работает has been updated так, что NULL поля перемещаются из параметризованных запросов и приложенных к SQL фильтра таким образом, это должно работать с v4.0.37 +, что теперь available on MyGet.

Вы можете также удалять строки в OrmLite по PrimaryKey с:

Db.DeleteById<TestTable>(entity.Id); 

Для общих методов, которые вы можете использовать метод T.GetId() расширения, чтобы получить значение поля Id, то есть:

Db.DeleteById<TestTable>(entity.GetId()); 

Или удалить с каждого неnull имущество в DELETE WHERE критерии, вы можете использовать:

Db.DeleteNonDefaults(entity); 
+0

Хорошо спасибо, но еще один вопрос. Почему даже если диалект ** SqlServerDialect.Provider ** сгенерированное предложение ** WHERE ** не будет соответствовать ни одному из строк? – Pizzaboy

+1

@Pizzaboy Поскольку он использует параметризованный запрос для выполнения фильтра и сравнивает нулевое поле с параметризованным значением (даже если это DbNull) дает ложное условие. Вы можете использовать 'Db.DeleteNonDefaults()', поэтому нулевые поля не используются в фильтре, в противном случае я предпочитаю удалять с использованием Первичного ключа с помощью 'Db.DeleteById()'. – mythz

1

Если вы выполняете те же утверждения в SSMS, и ничего не удаляется, потому что ни одна строка не соответствует критериям.

OrmLite ожидает, что первичный ключ объекта будет называться Id (с учетом регистра). Ваше свойство имеет имя ID, а атрибут [PrimaryKey] не указан. В этом случае OrmLite должен использовать все доступные поля в предложении WHERE, чтобы найти строки для удаления.

AutoIncrement не означает, что поле является ключевым, так как его значение автоматически генерируется сервером и исходит из столбца идентификации. То же самое относится и к SQL Server - столбец идентификации не является первичным ключом, вам нужно определить первичный ключ отдельно.

Вам необходимо либо переименовать ID в Id, либо добавить к нему атрибут [PrimaryKey].

Смежные вопросы