Che*_*hev 2 c# datacontext entity-framework repository entity-framework-4
在我们的应用程序中,我们使用存储库模式从数据存储介质中检索和保留数据.我们选择使用的媒介是实体框架4.这似乎是一种非常干净的做事方式,并且在99%的时间里工作得非常好.
现在我们遇到了一个问题.我们有两个存储库,如下所示:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
实体框架模型中的用户和角色实际上具有多对多的关系.有时我们希望获取现有用户和现有角色并将两者关联起来.通常情况下,如果您执行这样的简短示例代码段,这将非常有用:
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();
Run Code Online (Sandbox Code Playgroud)
这很有效,因为两个实体都是从同一个EF数据上下文对象中检索的.但是,在我们的应用程序中,每个存储库都会创建自己的数 因此,当我们尝试使用我们自己的架构执行上述操作时:
UserRepository userRepo = new UserRepository();
RoleRepository roleRepo = new RoleRepository();
User user = userRepo.GetUser("Fred");
Role roleToAdd = roleRepo.GetRole("Admin");
user.Roles.Add(roleToAdd);
userRepo.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
我们收到此错误:
无法定义两个对象之间的关系,因为它们附加到不同的ObjectContext对象.
集中此数据上下文的最佳方法是什么?显然,我不想在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);
}
Run Code Online (Sandbox Code Playgroud)
我可以这样做:
userRepo.AddUserToRole("Fred", "Admin");
userRepo.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
但这是实现这一目标的最佳方法吗?有没有更好的方法在每个请求上集中EF数据上下文,以便所有存储库使用相同的存储库而不是创建自己的存储库?如果是这样,我该怎么做?
任何帮助表示赞赏.
在存储库上使用构造函数注入来传递上下文.
public class UserRepository : IUserRepository
{
Entities dataContext;
public UserRepository(Entities entities)
{
this.dataContext = 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();
}
}
Run Code Online (Sandbox Code Playgroud)
告诉您的DI容器请求范围上下文生命周期.
例如,使用AutoFac,您将:
builder.RegisterType<Entities>().InstancePerHttpRequest();
builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerHttpRequest();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2314 次 |
| 最近记录: |