Подтвердить что ты не робот

Серверные ключи и генерируемые сервером значения не поддерживаются SQL Server Compact

Я только начал играть с инфраструктурой сущности, поэтому решил подключить его к существующей базе данных SQL Server CE. У меня есть таблица с первичным ключом IDENTITY (1, 1), но когда я попытался добавить объект, у меня есть вышеупомянутая ошибка.

Из MS Technet artice Я узнал, что

SQL Server Compact не поддерживает сущности с генерируемыми сервером ключами или значениями, когда он используется с Entity Framework. При использовании Entity Framework ключи сущностей могут быть помечены как созданные сервером. Это позволяет базе данных генерировать значение для ключа при вставке или создании сущности. Кроме того, нулевые или более свойства объекта могут быть помечены как генерируемые сервером значения. Дополнительные сведения см. В разделе "Сохраненный шаблон" в документации по платформе Entity Framework. SQL Server Compact не поддерживает сущности с генерируемыми сервером ключами или значениями, когда он используется с Entity Framework, хотя Entity Framework позволяет вам определять типы сущностей с помощью ключей или значений, сгенерированных сервером. Операция манипуляции данными с сущностью, которая имеет генерируемые сервером значения, генерирует исключение "Не поддерживается".

Итак, теперь у меня есть несколько вопросов:

  • Почему бы вам пометить ключ как сгенерированный сервером, если он не поддерживается и будет генерировать исключение? Это трудно сделать из цитированного абзаца.
  • Когда я попытался добавить StoreGeneratedPattern = "Identity" в свой объект entity, Studio жаловалась, что это запрещено. Что я делаю неправильно?
  • Какое наилучшее решение для этого ограничения (включая переход на другой БД)? Мои ограничения - нулевая установка и использование сущности framework.
4b9b3361

Ответ 1

Когда я ударил это ограничение, я изменил тип на uniqueidentifier

Ответ 2

Использовать уникальный идентификатор или генерировать значение ключа bigint/int вручную - ваш лучший вариант.

Что-то вроде этого возможно...

    private static object lockObject = new object();

    private static long nextID = -1;

    public static long GetNextID()
    {
        lock (lockObject)
        {
            if (nextID == -1) nextID = DateTime.UtcNow.Ticks; else nextID++;
            return nextID;
        }
    }

Это предполагает, что во время запуска приложения вы не генерируете более одной записи за галочку (плюс время остановки и перезапуска). Думаю, это разумное предположение, но если вы хотите полностью пуленепробиваемое (но более сложное) решение, прочитайте наивысший идентификатор из базы данных и увеличьте его.

Ответ 3

SQL CE версии 4.0 исправил эту проблему своим провайдером Entity Framework.

Ответ 4

Я просто ударил эту проблему тоже... mosttech ответ, вероятно, лучший вариант, GUID очень просты в использовании и риск столкновения ключей очень низок (хотя и не является неубедительным).

  • Почему бы вам пометить ключ как сгенерированный сервером, если он не поддерживается и будет генерировать исключение? Это трудно сделать из цитированного абзаца.

Так как SQL Server (не Compact) поддерживает его, и другие сторонние пользователи могут его поддерживать... Entity Framework не только для SQL Server Compact;)

Ответ 5

В моем случае все мои классы имеют первичный ключ с именем "ID"

Я создал интерфейс

public class IID
{
    public Int32 ID { get; set; }
}

Затем я создаю метод расширения

public static Int32 GetNextID<T>(this ObjectSet<T> objects)
    where T : class, IID
    {
        T entry = objects.OrderByDescending(u => u.ID).FirstOrDefault();
        if (entry == default(T))
            return 1;
        return entry.ID + 1;
    }

Затем, когда мне нужен новый идентификатор, я просто делаю это:

MyObject myobj = new MyObject();
myobj.ID = entities.MyTable.GetNextID();

Ответ 6

другой вариант заключается в использовании SqlCeResultSet в таблицах с столбцом идентификатора.

Ответ 7

У меня есть первичный ключ с именем ID с типом данных INT32 и столбец Identity

Просто сделайте это

MyEntity Entity = new MyEntity();

String Command;

command = "Insert into Message (Created, Message, MsgType) значения ('12/1/2014 ',' Hello World ', 5);  Entity.ExecuteStoreCommand(команда);

- Исключить первичный ключ в Statement Statement

- Поскольку SQLCE не поддерживает сгенерированные системой ключи

- Не используйте LINQ, потому что он поставляет значение по умолчанию для 0 для основных ключей, которое имеет тип данных INT