別名コードファーストで複数のID列を作成するにはどうすればよいですか?
クラスタリングのパフォーマンスのため、一般的な推奨事項は、で作成されたGUIDの代わりに、自動インクリメントされた整数列を使用することnewid()
です。
列を自動インクリメントとして宣言するには、アノテーションを使用して列を指定する必要があります[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
。
ただし、テーブルに含めることができるIDは1つだけです。
したがって、次のような基本モデルから始めます。
public abstract class ModelBase {
// the primary key
public virtual Guid Id { get; set; }
// a unique autoincrementing key
public virtual int ClusterId { get; set; }
}
次のように設定するにはどうすればよいですか。
- Guidは、コードではなくデータベースによって自動的に生成されます
ClusterId
自動インクリメントされます- Entity Framework Code Firstは、次のようなあらゆる種類のエラーをスローしません。
- 主キー列のプロパティが「StoreGeneratedPattern」から「Computed」に設定されているテーブルへの変更はサポートされていません。代わりに「Identity」パターンを使用してください。
参考までに、コードで自動的に生成する場合は、Idフィールドの注釈をスキップして、次のようにすることができます。
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();
}
}