Вопрос по asp.net-mvc, c#, entity-framework – Entity Framework автоматически генерирует GUID

23

Я новичок в EF, так что здесь идет. У меня есть класс, который содержит следующее

public class EmailTemplate
{
    public Guid Id { get; set; }

    [MaxLength(2000)]
    public string Html { get; set; }
}

Вот мой класс картографии

class EmailMapper : EntityTypeConfiguration<EmailTemplate>
    {
        public EmailMapper()
        {
            ToTable("EmailTemplate");

            HasKey(c => c.Id);
            Property(c => c.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            Property(c => c.Id).IsRequired();
        }
    }

Я пытаюсь позвонитьDbContext.SaveChanges(), но я получаю следующую ошибку:

Сведения об исключении: System.Data.SqlClient.SqlException: невозможно вставить значение NULL в столбец «Id», таблица «AutoSendConnection.dbo.EmailTemplates»; столбец не допускает пустых значений. Вставить не удается.

Что я делаю неправильно? Почему EF не создаст уникальный GUID?

Ваш Ответ

6   ответов
41

как показано ниже, и SQL Server автоматически сгенерирует значение при вставке.

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public Guid Id { get; set; }

Вы также можете удалить свой класс Mapper, поскольку он больше не нужен.

Этот ответ работает только для EF Core ... Пользователи EF6 сочтут это проблематичным. War
Если вы используете CodeFirst, EF может не обнаружить это изменение. Вы можете удалить свою таблицу и добавить новую миграцию. Virgar Poulsen
На самом деле, это то же самое, что OP уже сделал в своем коде. Хотя это обходной путь, который устраняет проблему, он не отвечает первоначальной проблеме. Alisson
В создаваемой миграции не задано значение sql по умолчанию, поэтому это не работает (даже при создании таблицы с нуля). War
-1

Базовое обновление Entity Framework:

Там нет необходимости использовать[DatabaseGenerated(DatabaseGeneratedOption.Identity)].
Там нет необходимости использоватьfluent API

EF Core автоматически позаботится об этом и сгенерирует Id для первичного ключа

Пример:

public class DummyEntity
{
    public Guid Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

}

засеивание

    _context.DummyEntities.Add(new DummyEntity
    {
        FirstName = "Abc",
        LastName = "Def",
        Postion = "User",
    });

    _context.SaveChanges();
Голосовали против, потому что это не кажется, это точно. Когда я генерирую свою миграцию, defaultValue устанавливается на новый Guid («00000000-0000-0000-0000-000000000000»)). Пожалуйста, обновите свой ответ. Rogala
Этот ответ является неправильным и крайне плохой практикой. в этом так много проблем, и мне нужна полная ветка на форуме, чтобы исправить все проблемы в ней. War
На EntityFrameworkCore 1.0.4 этого было недостаточно. Мне пришлось использовать entity.Property (e => e.Id) .ValueGeneratedOnAdd (); который сделал трюк для меня. Martin Kunc
Вы правы, что ядро ​​ef заботится об этом, но оно не создает таблицу базы данных, которая должным образом заботится об автоматической генерации этого guid, например, на SQL-сервере не устанавливается значение по умолчанию или не включается свойство автоматической генерации. Bailey Miller
12

Используйте свободный API

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Node>().Property(x => x.ID).HasDefaultValueSql("NEWID()");
}
Что такое узел? Здесь говорится, что это сборка может отсутствовать. Я использую EF 6.1. Отредактировано: это модель. acido
Зависит от версии. Если вы в ядре .net, то я рекомендую шпаргалку в моем ответе Mohsen Tabareh
@acido Node - это сущность в EF, может быть любой таблицей БД Mohsen Tabareh
Я получаю сообщение об ошибке с HasDefaultValueSql, которого больше нет в EF 6.1. Я пытаюсь найти альтернативу acido
3

онфигурации сопоставления.

Это показывает пример:blog.jongallant.com/2013/04/... Liviu M.
Пожалуйста, смотрите мой класс отображения в исправленном вопросе, куда бы я поместил newsequentialid ()? Сначала я пытаюсь сделать это с помощью кода и просто подумал, что EF справится с этим? user2859298
2

ом сервере Sql и передать GUID как ноль

Я делал это в SSMS.

Последовательный идентификатор вызывает меньшую фрагментацию индексов, следовательно, лучшую производительность запросов Liviu M.
Даже если вы установили значение ID по умолчанию в качестве NewID () на сервере SQL, вам все равно нужно изменить файл .edmx, если свойство StoreGeneratedPattern еще не установлено. ссылка:developerhandbook.com/entity-framework/... Chinh Phan
@ChinhPhan В стандартных случаях я не думаю, что нам нужно менять какой-либо XML. Я использую мастер для создания файлов EDMX, и все работает нормально. Moons
1

чтобы автоматически генерировать идентификатор, например, следующую схему:

CREATE TABLE [dbo].[MyTable](
    [MyId] [uniqueidentifier] NOT NULL CONSTRAINT [DF_Booking_BookingId]  DEFAULT (newsequentialid())
    )

Затем в отображении кода сначала я указываю следующее, чтобы сообщить Entity Framework, что база данных позаботится о создании значения при вставке.

Property(a => a.MyId).IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
С помощью кода сначала мы не пишем SQL, который выполняет миграция, а код миграции, который вы там видите, не приводит к тому SQL, который вы показали, см. Мой ответ для моих деталей. War

Похожие вопросы