EFパッケージベースのデータ操作後のDbContextの問題は,コンテキストが一意であることを保証する必要がある.
EFを使用してデータベースを操作し、DbContext(データベース操作コンテキストクラス)を抽出して多重化します.
モデル対応の倉庫はベース倉庫を継承し,基本的な操作方法を持つ.
対応するRepositoryごとに作成される新しいDbContextデータベースコンテキストオブジェクト.
では、1つのリクエストで2つのテーブルのデータを操作する必要がある場合はどうすればいいですか?ユーザーの追加、ロールの追加
2つのRepositoryを作成し、それぞれSaveChanges()を作成します.
UserRepository user_rep = new UserRepository();
...
user_rep.SaveChanges();
RoleRepository role_rep = new RoleRepository();
xxx
role_rep.SaveChanges();
これにより、データベースが2回操作され、データの一貫性が保証されず、異常が発生する可能性があります.明らかに望ましくない.
私の現在の解決策は、DbContextコンテキストオブジェクトをスレッド内の唯一のデータ・ホールに配置することです.
httpリクエストのたびに新しいスレッドが開きます.1つのスレッド(機能)でDbContextが唯一であることを保証します.
これで1つのActionでSaveChangesを1回だけコミットすればよい.データベースへのアクセスを削減し、データの一貫性を保証します.
public class BaseDBContext: DbContext
{
public BaseDBContext() : base("name=xxSysEntities")
{
}
}
その後、基本的な倉庫を確立し、パッケージを追加していくつかの方法を変更します.public class BaseRepository where TEntity : class, new()
{
private DbContext db;
private readonly DbSet dbSet;
public BaseRepository()
{
this.db = new BaseDbContext();
this.dbSet = db.Set();
}
public void Add(TEntity Model)
{
this.dbSet.Add(Model);
}
...void saveChanges(); ..
}
モデル対応の倉庫はベース倉庫を継承し,基本的な操作方法を持つ.
対応するRepositoryごとに作成される新しいDbContextデータベースコンテキストオブジェクト.
では、1つのリクエストで2つのテーブルのデータを操作する必要がある場合はどうすればいいですか?ユーザーの追加、ロールの追加
2つのRepositoryを作成し、それぞれSaveChanges()を作成します.
UserRepository user_rep = new UserRepository();
...
user_rep.SaveChanges();
RoleRepository role_rep = new RoleRepository();
xxx
role_rep.SaveChanges();
これにより、データベースが2回操作され、データの一貫性が保証されず、異常が発生する可能性があります.明らかに望ましくない.
私の現在の解決策は、DbContextコンテキストオブジェクトをスレッド内の唯一のデータ・ホールに配置することです.
httpリクエストのたびに新しいスレッドが開きます.1つのスレッド(機能)でDbContextが唯一であることを保証します.
public static DbContext GetCurrentDbContext()
{
//CallContext: ( )
// DbContext , 。
DbContext dbContext = CallContext.GetData("DbContext") as DbContext;
if (dbContext == null) //
{
// ( )EF
dbContext = new BaseDBContext();
CallContext.SetData("DbContext", dbContext);
}
return dbContext;
}
倉庫でDbContextを作成するときは、これを使って作成すれば良いので、newの新しいDbContextには行かない. public BaseRepository()
{
this.db = DbContextFactory.GetCurrentDbContext();
this.dbSet = db.Set();
}
これで1つのActionでSaveChangesを1回だけコミットすればよい.データベースへのアクセスを削減し、データの一貫性を保証します.