Код структуры Entity Framework Сначала используйте Guid как идентификатор с другой колонкой Identity

aka Как мы можем создать несколько столбцов идентификации в Code First?

Из-за производительности кластеров общая рекомендация заключается в том, чтобы использовать столбец с автоинкрементным целым числом вместо GUID, созданного с помощью функции newid() .

Чтобы объявить столбец как автоинкремент, вы должны указать его с помощью annotations [DatabaseGenerated(DatabaseGeneratedOption.Identity)] .

Но вы можете иметь только одно удостоверение в таблице.

Итак, начиная с базовой модели, например:

 public abstract class ModelBase { // the primary key public virtual Guid Id { get; set; } // a unique autoincrementing key public virtual int ClusterId { get; set; } } 

как мы настраиваем его так, чтобы:

  1. Руководство автоматически генерируется базой данных, а не кодом
  2. ClusterId автоинкрементный
  3. Entity Framework Code Сначала не генерирует всевозможные ошибки, например:
    • Модификации таблиц, в которых столбец первичного ключа имеет свойство «StoreGeneratedPattern», установленное в «Computed», не поддерживается. Вместо этого используйте шаблон «Идентичность».

FYI , если вы хотите автоматически генерировать его в коде, вы можете пропустить аннотацию в поле Id и сделать что-то вроде:

 public abstract class AbstractContext : DbContext { ///  /// Custom processing when saving entities in changetracker ///  ///  public override int SaveChanges() { // recommended to explicitly set New Guid for appropriate entities -- http://msdn.microsoft.com/en-us/library/dd283139.aspx foreach (var entry in ChangeTracker.Entries().Where(e => e.State == EntityState.Added) ) { // only generate if property isn't identity... Type t = entry.Entity.GetType(); var info = t.GetProperty("Id").GetCustomAttributes( typeof(DatabaseGeneratedAttribute), true).Cast().Single(); if (info.DatabaseGeneratedOption != DatabaseGeneratedOption.Identity) { entry.Entity.Id = Guid.NewGuid(); // now we make it } } return base.SaveChanges(); } } 

Это закончилось для меня, Entity Framework 5.

  1. Отключить автоматическую миграцию
  2. Миграция для создания исходной таблицы, без излишеств
  3. Объявить ClusterId как идентификатор (аннотация)

     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public override int ClusterId { get; set; } 
  4. мигрировать

  5. Объявить Id свойства pk как идентификатор после того, как он был обновлен

     [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public override Guid Id { get; set; } 
    • бонус : EF, похоже, предполагает, что Id является первичным ключом, поэтому вам не нужно [Key, Required]
  6. Создайте код миграции, например add-migration TrickEfIntoAutogeneratingMultipleColumns

  7. В методе Up() в AlterColumn сообщите базе данных, чтобы автогенерировать GUID, объявив defaultSqlValue
    • AlterColumn(theTable, "Id", c => c.Guid(nullable: false, identity: true, defaultValueSql: "newid()"));
  8. мигрировать

Это похоже на «трюк» EF, в том смысле, что он предполагает, что оба столбца являются тождествами и реагируют соответственно. Во время миграции он пытается сделать другой столбец личным, но, похоже, не волнует, когда это тихо проваливается – в итоге вы попадаете в один символ с именем Identity, а другой – по умолчанию.

Во время нормальной работы кода, когда EF проходит шаги SaveChanges / ChangeTracking, поскольку он видит свойство Id как идентификатор, он делает это «назначить временный ключ» , чтобы он не пытался использовать значение по умолчанию 0000000 …, и вместо этого позволяет генерировать базу данных с использованием указанной вами функции значений по умолчанию.

(Я бы подумал, что аннотировать это поле, поскольку Computed выполнил бы то же самое, но … ошибки, о которых я упомянул в вопросе … boo …)

И поскольку поле ClusterId также является идентификатором в коде и действительно является идентификатором в базе данных, оно также ClusterId .

  • Перенос EF для изменения типа данных столбцов
  • Уникальные ограничения ключа для нескольких столбцов в Entity Framework
  • Первый код - сначала модель / firebase database
  • Entity Framework 4 выборочно ленивые свойства загрузки
  • Метод DbSet.Find смехотворно медленный по сравнению с .SingleOrDefault для ID
  • как обновить объект в Entity Framework 4 .NET
  • Код структуры Entity сначала удаляется с помощью каскада
  • Добавление подсказки при вызове функции с табличными значениями
  • Использование MySQL с платформой Entity Framework
  • Платформа Entity Framework и пул соединений
  • Считаете ли вы целесообразным перейти на Entity Framework?
  • Давайте будем гением компьютера.