Сгенерированные сервером ключи и сгенерированные сервером значения не поддерживаются SQL Server Compact - PullRequest
35 голосов
/ 15 марта 2009

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

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

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

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

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

Ответы [ 7 ]

24 голосов
/ 15 марта 2009

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

17 голосов
/ 23 мая 2009

Используйте ваш уникальный идентификатор или сгенерируйте значение ключа 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;
        }
    }

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

6 голосов
/ 03 октября 2011

SQL CE версии 4.0 исправил эту проблему с помощью поставщика Entity Framework.

4 голосов
/ 12 мая 2011

В моем случае все мои классы имеют первичный ключ с именем "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();
4 голосов
/ 09 декабря 2009

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

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

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

1 голос
/ 23 декабря 2010

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

0 голосов
/ 07 апреля 2014

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

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

MyEntity Entity = new MyEntity ();

Строковая команда;

команда = "Вставить в сообщение (создано, сообщение, MsgType) значения ('12 / 1/2014 ',' Hello World ', 5); Entity.ExecuteStoreCommand (команда);

- исключить первичный ключ из оператора вставки

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

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

...