拡張メソッドはスレッドセーフである可能性があり、スレッドの書き方によってスレッドが安全でない可能性があります。
あなたのメソッドはスレッドセーフですが、DbContext
は別のスレッドからアクセスされます。これは妥当な制限であり、理由はDbContext
は実際にスレッドセーフなクラスではありません。 (Multiple Active Result Setsを有効にするとこの制限は取り除くことができますが、それは良い判断の原因ではありませんDbContext
tracks data)。
これは、単一の事業運営のためのDbContext
を作成することをお勧めしますし、すぐにはにそれを処分する - それはway of the Unit Of Work patternです。
F.e.ウェブAPIシナリオでは、各HTTPリクエストに対して異なるDbContext
を作成することができ、あるいは、あなたは操作ごとに異なるコンテキストを作成することができます。
public class UserRepository : IUserRepository
{
public User async GetByIdAsync(int id)
{
using (var dbContext = new MyDbContext())
{
var data = await dbContext.FindAsync((UserData user) => user.Id == id);
return new User(data);
}
}
}
このコードでは正しく動作FindAsync
方法を、それを呼び出すのに便利ではありません。署名を変更する:
public static class DBSetHelper
{
public static async Task<T> FindAsync<T>(
this DbSet<T> set,
Expression<Func<T, bool>> match)
where T : BaseEntity
{
return await set.SingleOrDefaultAsync(match);
}
}
. . .
public class UserRepository : IUserRepository
{
public User async GetByIdAsync(int id)
{
using (var dbContext = new MyDbContext())
{
var data = await dbContext.Users.FindAsync(user => user.Id == id);
return new User(data);
}
}
}