Код Entity Framework сначала использует Guid в качестве идентификатора с другим столбцом идентификатора

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

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

Чтобы объявить столбец автоинкрементным, вы должны указать его с помощью аннотации [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. Guid автоматически генерируется базой данных, а не кодом
  2. ClusterIdавтоматически увеличивается
  3. Entity Framework Code First не выдает всевозможные ошибки, такие как:
    • Изменения в таблицах, в которых столбец первичного ключа имеет свойство StoreGeneratedPattern со значением Computed, не поддерживаются. Вместо этого используйте шаблон «Идентичность».

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

public abstract class AbstractContext : DbContext {

  /// <summary>
  /// Custom processing when saving entities in changetracker
  /// </summary>
  /// <returns></returns>
  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<ModelBase>().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<DatabaseGeneratedAttribute>().Single();

          if (info.DatabaseGeneratedOption != DatabaseGeneratedOption.Identity) {
              entry.Entity.Id = Guid.NewGuid(); // now we make it
          }
      }
      return base.SaveChanges();
  }

}
37
задан drzaus 17 August 2012 в 20:37
поделиться