私たちのアプリケーションでは、リポジトリパターンを使用して、データストレージメディアからデータを取得して保持します。使用することを選択したメディアはEntity Framework 4です。これは非常にクリーンな方法で、99%の時間を費やしています。Entity FrameworkのデータコンテキストをWebアプリケーションに集中させるにはどうすればよいですか?
今、問題が発生しています。
public class UserRepository : IUserRepository
{
Entities dataContext = new Entities();
public User GetUser(string username)
{
return dataContext.Users.SingleOrDefault(x => x.Username == username);
}
// ... more CRUD-style methods that are not relevant to this question.
public void SaveChanges()
{
dataContext.SaveChanges();
}
}
public RoleRepository : IRoleRepository
{
Entities dataContext = new Entities();
public Role GetRole(string name)
{
return dataContext.Roles.SingleOrDefault(x => x.Name == name);
}
// ... more CRUD-style methods that are not relevant to this question.
public void SaveChanges()
{
dataContext.SaveChanges();
}
}
ユーザーとロールが実際にEntity Frameworkのモデルでは、多くの関係に多くを持っている:私たちは、このような2つのリポジトリを持っています。時には、既存のユーザーと既存の役割を引き継いで、その2つを関連づけたい場合もあります。両方のエンティティが同じEFデータコンテキストオブジェクトから取得されているので、これは素晴らしい作品
Entities dataContext = new Entities();
Role roleToAdd = dataContext.Roles.Single(x => x.Name == "Admin");
User user = dataContext.Users.Single(x => x.Username == "Fred");
user.Roles.Add(roleToAdd);
dataContext.SaveChanges();
:あなたはこのように短いサンプルコードスニペットを行う場合、通常、これは素晴らしい仕事です。しかし、我々のアプリケーションでは、各リポジトリは独自のデータコンテキストオブジェクトを作成します。だから我々は我々自身のアーキテクチャと上記と同じことをしようとすると:
UserRepository userRepo = new UserRepository();
RoleRepository roleRepo = new RoleRepository();
User user = userRepo.GetUser("Fred");
Role roleToAdd = roleRepo.GetRole("Admin");
user.Roles.Add(roleToAdd);
userRepo.SaveChanges();
私たちは、このエラーを取得する:
The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
このデータコンテキストを一元化するための最良の方法は何ですか?明らかに、私はUserRepository内でGetRoleメソッドを複製したくないのです。なぜなら、それは冗長で愚かなためです。私は、ユーザー名とロール名になりますUserRepositoryに、より詳細な方法を行うことができ、このように、取得し、それらを関連付けるために同じデータコンテキストを使用しています。
public void AddUserToRole(string username, string role)
{
User user = dataContext.Users.Single(x => x.Username == username);
Role roleToAdd = dataContext.Roles.Single(x => x.Name == role);
user.Roles.Add(roleToAdd);
}
私はその後、ちょうど行うことができます:
userRepo.AddUserToRole("Fred", "Admin");
userRepo.SaveChanges();
これを達成するための最善の方法はありますか?すべてのリポジトリが独自のリポジトリを作成するのではなく、同じリポジトリを使用するように、各リクエストにEFデータコンテキストを集中させるより良い方法はありますか?もしそうなら、どうすればいいのですか?
何か助けていただければ幸いです。
なぜ私はそれを考えなかったのですか? 'kernel.Bind .ToSelf().InRequestScope()'がトリックをしました!ありがとうございました。 –
Chev
私たちはNinjectを使用していますが、同じ概念が美しく適用されます。 6分で受け入れます。 – Chev
ひとつ追加します。 'IUserRepository.SaveChanges()'には注意してください。 'User'だけでなく、全体の要求を原子的に保存するようになりました。それはおそらく*あなたが望むものですが、それがその範囲にある場合は明白ではないかもしれません。 –