Отключение идентификатора (автоинкремент) в первичном ключе целых чисел с использованием кода в первую очередь - PullRequest
37 голосов
/ 26 августа 2011

Я использую подход, основанный на коде, в приложении ASP.NET MVC 3, и все целочисленные первичные ключи в моделях (public int Id { get; set; }) по умолчанию настроены как идентификаторы с автоматическим приращением. Как это отключить и включить способ ручного ввода целого числа для первичного ключа?

Фактическая ситуация такова, что целые числа Id имеют особое значение, и поэтому я хотел бы, чтобы их можно было выбирать при создании и позже редактировать. Было бы идеально, если бы во время создания целое число не было задано, оно автоматически увеличивается, в противном случае используется указанное значение. Но редактируемые первичные поля - моя основная потребность. Есть ли способ сделать это элегантно в ASP.NET MVC 3?

Ответы [ 6 ]

51 голосов
/ 24 ноября 2011

Используйте следующие параметры аннотации данных:

  • [System.ComponentModel.DataAnnotations.KeyAttribute()]
  • [System.ComponentModel.DataAnnotations.DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]
27 голосов
/ 25 ноября 2011

Вы можете использовать FluentMapping:

modelBuilder.Entity<*entityname*>().Property(m => m.*fieldname*)
             .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
3 голосов
/ 28 августа 2017

Если вы хотите использовать свободный API с EntityFramework Core 2.0, вы пишете:

modelBuilder.Entity<*myEntity*>()
  .Property(e => e.*myFieldname*)
  .ValueGeneratedNever();
2 голосов
/ 05 декабря 2012

Я только что установил последнюю принятую EntityFramework.dll версии 5.0.0, я полагаю ...

однако, я наполовину запутался, так как существует Runtime-версия v4.0.30319и версия 4.4.0.0, но, я уверен, с веб-сайта, на который я ссылался при поиске (который велел мне установить через «Package Mangager Console», из которого вы попадаете через меню в VS »Tools | Library Package Manager |Консоль диспетчера пакетов »и введите в приглашении« PM> »« Install-Package EntityFramework [необязательно: номер версии или -Pre для самого последнего предварительного выпуска (бета-версия)] »), это было 5.0.0.

... и имеется атрибут "System.CompnentModel.DataAnnotations.DatabaseGenerated (Computed, Identity или None) (предыдущая версия) или [...]. Schema.DatabaseGenerated (последняя версия)", который вы могли быиспользовать.Так что либо используйте этот атрибут, либо используйте идею свободного отображения, как упомянуто выше (Уильям Хаак (отредактировано Remo Gloor)), и, если не код сначала (то есть изменение производства), то, как уже упоминалось выше (Адам Тулипер), вам нужно будет написать ивыполнить сценарий отключения, чтобы отключить вставку идентификатора.Кроме того, если вы не предоставите идентификатор, вы можете смоделировать вставку идентификатора, извлекая MAX (ID) + 1 из таблицы в коде (и помните о проблемах параллелизма в многопользовательской среде) или в триггере.В качестве альтернативы, если вы хотите закрыть отверстия, как указано в выражении, вы, вероятно, могли бы сделать это и в триггере, перехватывая вставленную строку и проверяя, установлен ли столбец идентификатора; если это так, продолжайте вставку в противном случае, сначала установите значение.Один из подходов к дырам в пробках - это использовать этот трюк (который я видел на каком-то веб-сайте, который я не могу вспомнить, поэтому я немного догадываюсь здесь), когда вы эффективно выполняете анти-внутреннее объединение из некоторого большого стола с помощью простогоодин столбец округлений в таблице, чтобы найти первый доступный неиспользуемый идентификационный номер (т. е. найти первое округление, не являющееся членом целевой таблицы).

В SQL Server 2005 и более поздних версиях:

CREATE TRIGGER updInsYourTable_PlugHolesOnIDIfNull 
ON YourTable
FOR update, insert AS
BEGIN
    DECLARE @ID INT
    SELECT @ID = ID FROM INSERTED
    IF @ID IS NULL
    BEGIN
        ;WITH CTE_StagedNumbers AS
        (
            SELECT ROW_NUMBER() OVER (ORDER BY o.object_id) AS NextFreeIdentity
            FROM (  SELECT object_id FROM sys.objects
                 -- UNION ALL 
                 -- SELECT object_id FROM sys.objects
                 /* NB: Here if sys.objects is not larger enough say on a small schema 
                    configured database then use a different table otherwise you can 
                    always union all on the same table as many times as you want to 
                    double, triple etc. its size. */
                 )  o
        )
        UPDATE YourTable
        SET ID = (
                    SELECT TOP 1 NextFreeIdentity
                    FROM CTE_StagedNumbers
                    WHERE NextFreeIdentity NOT IN (SELECT ID FROM YourTable)
                 )
        WHERE ID IS NULL
    END
END
GO

Обратите внимание, что CTE_StagedNumbers не обязателен, он просто необходим для выделения, и основной трюк не обязательно заключается в настройке номера строки, но, если вы должны были установить постоянную промежуточную таблицу (скажем, StagedNumbers)только с одним целочисленным столбцом без автоматической идентификации (скажем, NextFreeIdentity INT NOT NULL PRIMARY KEY), (кроме примечания: определение YourTable для столбца идентификатора должно принимать значения NULL, поскольку мы используем триггер after), предварительно заполненное последовательным положительным целым числомзначения, начинающиеся с 1, используя вышеупомянутую технику, затем удалите CTE altogether и замените CTE_StagedNumbers в конечном выборе на StagedNumbers, тогда это будет наиболее эффективно.

1 голос
/ 28 июля 2017

использовать атрибут:

public class MessageSubject
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Id { get; set; }
        public string Title { get; set; }
        public string Comment { get; set; }
        public bool BuildIn { get; set; }
    }
1 голос
/ 26 августа 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...