应EF的DbContext将在每个事务创建 [英] should EF dbContext be created on every transaction

查看:151
本文介绍了应EF的DbContext将在每个事务创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找出管理的DbContext的最佳方式。我见过code样本不处理,我见过的人说,这是一个坏主意。是不是适合我做类似下面?另外,我应该把每一笔交易,包括读取,在一个新的DbContext?这可能是另一个问题,但有关的EntityState必要的组成部分?

 公共抽象类GenericRepository< T>其中T:EntityData
{
    保护MyDbContext上下文
    {
        {返回新MyDbContext(); }
    }

    公共t保持(T obj)以
    {
        牛逼的项目;
        使用(VAR上下文语境=)
        {
            VAR组= context.Set< T>();

            如果(String.IsNullOrEmpty(obj.Id))
                项目= set.Add(OBJ);
            其他
            {
                项目= set.Find(obj.Id);
                项目= OBJ;
            }

            //来自另一个code样品
            VAR项= context.Entry(项目);
            如果(entry.State == EntityState.Detached)
            {
                //需要设置修改,因此任何分离的实体被更新
                //否则他们不会跨越到数据库发送。
                //因为它会一直范围之外,更改跟踪
                //就不会发生反正,所以我们不知道关于它的状态 - 保存!
                set.Attach(项目);
                context.Entry(项目).State = EntityState.Modified;
            }
            context.SaveChanges();
        }

        返回的项目;
    }
}
 

修改
我也有一个实现此功能下一个扩展类。上下文不被包裹在一个using语句在此查询,所以我有点怀疑我的code。

 公开的IQueryable< T> FindByAccountId(字符串帐户ID)
{
    从项目的Context.Set&LT返回; T>()
        让用户= UserRepository.FindByAccountId(帐户ID).FirstOrDefault()
        其中,item.UserId == user.Id
        选择项目;
}
 

解决方案

上下文确实应该在每个请求的基础。请求进来,并创建一个新的环境。此上下文用于然后在相应的请求的结束设置的请求的剩余部分。这使您可以要求长事务的好处,以及所强调的HamidP,你也有缓存的实体的好处;也就是说装入上下文的任何实体可以通过无实体框架需要查询数据库中检索被加载

如果你使用任何一种控制容器的倒置,如StructureMap,那么你可以轻松地创建HTTP请求的约束背景下通过配置,如:

  this.For<的DbContext>()HybridHttpOrThreadLocalScoped()使用<&的DbContext GT;();
 

你就能够注入你的的DbContext (或它的衍生物)到你的资料库,并留下您选择的IOC容器在最后处置的背景下请求。如果你是在同一环境到另一个存储库注入,那么你会收到背景下的同一个实例。

我希望这有助于!

I'm trying to figure out the best way to manage the DbContext. I've seen code samples that don't dispose and I've seen people say that that is a bad idea. Is it appropriate for me to do something like below? Also, should I put every transaction, including reads, in a new DbContext? This might be another question, but is the part about the EntityState necessary?

public abstract class GenericRepository<T> where T : EntityData
{
    protected MyDbContext Context
    {
        get { return new MyDbContext(); }
    }

    public T Save(T obj)
    {
        T item;
        using (var context = Context)
        {
            var set = context.Set<T>();

            if (String.IsNullOrEmpty(obj.Id))
                item = set.Add(obj);
            else
            {
                item = set.Find(obj.Id);
                item = obj;
            }

            // taken from another code sample
            var entry = context.Entry(item);
            if (entry.State == EntityState.Detached)
            {
                //Need to set modified so any detached entities are updated 
                // otherwise they won't be sent across to the db. 
                // Since it would've been outside the context, change tracking 
                //wouldn't have occurred anyways so we have no idea about its state - save it!
                set.Attach(item);
                context.Entry(item).State = EntityState.Modified;
            }
            context.SaveChanges();
        }

        return item;
    }
}

EDIT
I also have an extended class that implements this function below. The context is not being wrapped in a using statement in this query, so I'm a little suspicious of my code.

public IQueryable<T> FindByAccountId(string accountId)
{
    return from item in Context.Set<T>()
        let user = UserRepository.FindByAccountId(accountId).FirstOrDefault() 
        where item.UserId == user.Id
        select item;
}

解决方案

Contexts should really be on a per request basis. The request comes in and a new context is created. This context is used for the remainder of the request then disposed of at the end of the request accordingly. This gives you the benefit of request long transactions, and as highlighted by HamidP, you also have the added benefit of cached entities; meaning that any entities loaded into the context can be loaded by retrieved without Entity Framework needing to query the database.

If you're using any kind of inversion of control container such as StructureMap then you can easily create HTTP request bound contexts by a configuration such as:

this.For<DbContext>().HybridHttpOrThreadLocalScoped().Use<DbContext>();

You're then able to inject your DbContext (or a derivative of it) into your repository and leave your IOC container of choice to dispose of the context at the end of the request. If you were to inject the same context into another repository then you'd receive the same instance of the context.

I hope this helps!

这篇关于应EF的DbContext将在每个事务创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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