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

Отключение идентификации (автоинкремент) для целочисленного первичного ключа с использованием кода сначала

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

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

4b9b3361

Ответ 1

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

  • [System.ComponentModel.DataAnnotations.KeyAttribute()]
  • [System.ComponentModel.DataAnnotations.DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]

Ответ 2

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

modelBuilder.Entity<*entityname*>().Property(m => m.*fieldname*)
             .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

Ответ 3

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

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

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

В 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) (кроме NB: определение YourTable для столбца ID должно принимать значение null при использовании после триггера), предварительно заполненное consequtive положительными целыми значениями, начиная с в 1, используя вышеуказанный метод, затем полностью удалите CTE и замените CTE_StagedNumbers в окончательном выборе с помощью StagedNumbers, тогда это будет наиболее эффективным.

Ответ 4

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

Ответ 5

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

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

Ответ 6

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

modelBuilder.Entity<*myEntity*>()
  .Property(e => e.*myFieldname*)
  .ValueGeneratedNever();