你如何集中在Web应用程序中的实体框架数据上下文? [英] How do you centralize the Entity Framework data context in a web application?

查看:120
本文介绍了你如何集中在Web应用程序中的实体框架数据上下文?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的应用中使用存储库模式检索,从我们的数据存储介质持久化数据。我们选择使用介质为实体框架4.这似乎是一个非常干净的方式来做事,并已工作时间大99%。

In our application we use the repository pattern to retrieve and persist data from our data storage medium. The medium we opted to use is Entity Framework 4. This seems to be a very clean way to do things and has worked great 99% of the time.

现在我们遇到的问题。我们有两个仓库,像这样的:

Now we are encountering an issue. We have two repositories, like this:

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();
    }
}



用户和角色其实有许多人在许多关系实体框架模型。有时候,我们想利用现有的用户和现有的角色和两个关联。一般来说,如果你做一个简短的示例代码片段是这样,这将极大的工作:

Users and Roles actually have a many to many relationship in the Entity Framework model. Sometimes we want to take an existing user and an existing role and associate the two. Normally this would work great if you do a short sample code snippet like this:

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();

由于两个实体正在从同一EF数据上下文对象中得到这个伟大的工程。然而,在我们的应用程序的每个存储库中创建自己的数据上下文对象。因此,当我们尝试做相同的上面用我们自己的架构:

This works great because both entities are being retrieved from the same EF data context object. However, in our application each repository creates its own data context object. So when we try to do the same as the above with our own architecture:

UserRepository userRepo = new UserRepository();
RoleRepository roleRepo = new RoleRepository();
User user = userRepo.GetUser("Fred");
Role roleToAdd = roleRepo.GetRole("Admin");
user.Roles.Add(roleToAdd);
userRepo.SaveChanges();

我们得到这个错误:

两个对象之间的关系不能被限定,因为它们连接到不同的ObjectContext对象

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.

是什么集中这个数据上下文最好的方法?很显然,我不想在UserRepository内复制GetRole方法,因为这将是多余的和愚蠢的。我可以做这发生在一个用户名和角色名的UserRepository更详细的方法,然后使用相同的数据上下文检索和他们关联起来,像这样的:

What is the best way to centralize this data context? Obviously I don't want to duplicate a GetRole method within the UserRepository because that would be redundant and silly. I could just do a more verbose method on the UserRepository that takes in a username and a rolename, then uses the same data context to retrieve and associate them, like this:

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);
}



然后我可以只是做:

I could then just do:

userRepo.AddUserToRole("Fred", "Admin");
userRepo.SaveChanges();



但是,这是最好的方式做到这一点?有没有更好的办法,让所有仓库使用同一个,而不是创建自己的集中对每个请求的EF数据上下文?如果是的话,我会怎么做呢?

But is that the best way to accomplish this? Is there a better way to centralize the EF data context on each request so that all repositories use the same one instead of creating their own? If so, how would I do that?

任何帮助表示赞赏。

推荐答案

在资源库中使用构造函数注入通过上下文

Use constructor injection on the repository to pass the context.

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();
    }
}

告诉你的DI容器要求范围的情况下寿命。

Tell your DI container to request-scope the context lifetime.

例如,与AutoFac您可以:

E.g., with AutoFac you would:

builder.RegisterType<Entities>().InstancePerHttpRequest();
builder.RegisterType<UserRepository>().As<IUserRepository>().InstancePerHttpRequest();
builder.RegisterControllers(typeof(MvcApplication).Assembly);

这篇关于你如何集中在Web应用程序中的实体框架数据上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆