UnitOfWork和实体框架上下文 [英] UnitOfWork and Entity Framework Contexts

查看:147
本文介绍了UnitOfWork和实体框架上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图解决的问题是这个;我们正在使用实体框架来访问我们的Oracle数据库,它具有1200-1500个表。现在记住,我们没有访问它们,但可能有800多个访问。我们正在使用UnitOfWork - > Repository - >服务模式,并且工作得很好,但是我们正在努力找出是否应该有一个大的DbContext,或者是特定于手头任务的多个小的上下文。 >

我们的UnitOfWork使用如下所示的EFUnitOfWorkBase设置:

  public abstract class EFUnitOfWorkBase :IUnitOfWork 
{
private bool isDisposed = false;

public DbContextBase Context {get;组;

protected EFUnitOfWorkBase(DbContextBase context)
{
Context = context;
}

public int Commit()
{
return Context.SaveChanges();
}

public void Dispose()
{
if(!isDisposed)
Dispose(true);
GC.SuppressFinalize(this);
}

private void Dispose(bool disposal)
{
isDisposed = true;
if(disposal)
{
if(this.Context!= null)
this.Context.Dispose();
}
}

public IRepository< TEntity> GetRepository< TEntity>()其中TEntity:Common.EntityBase< TEntity>
{
return new Repository< TEntity>(this);
}
}

我们创建的任何工作单元都扩展了基础,提供上下文,如下所示:

  public class EmployeeDirectoryUnitOfWork:EFUnitOfWorkBase 
{
public EmployeeDirectoryUnitOfWork(string connectionString)
:base(new EmployeeDirectoryContext(connectionString))
{
}
}

DbContext通过工作单元传递一个连接字符串。



存储库看起来像这样:

  public abstract class RepositoryBase< TEntity> :IRepository< TEntity>其中TEntity:class 
{
protected DbContextBase Context;
protected DbSet< TEntity> EntitySet的;

public RepositoryBase(EFUnitOfWorkBase unitOfWork)
{
Enforce.ArgumentNotNull(unitOfWork,unitOfWork);

上下文= unitOfWork.Context;
EntitySet = Context.Set< TEntity>();
}

public TEntity Add(TEntity entity)
{
Enforce.ArgumentNotNull(entity,entity);

返回EntitySet.Add(entity);
}

public TEntity Attach(TEntity entity)
{
Enforce.ArgumentNotNull(entity,entity);

返回EntitySet.Attach(entity);
}

public TEntity删除(TEntity entity)
{
Enforce.ArgumentNotNull(entity,entity);

返回EntitySet.Remove(entity);
}

public System.Linq.IQueryable< TEntity> Query()
{
return EntitySet.AsQueryable();
}

public TEntity Save(TEntity entity)
{
Enforce.ArgumentNotNull(entity,entity);

附加(实体);
Context.MarkModified(entity);

返回实体;
}
}

有关如何最好地处理这种情况的任何建议? / p>

解决方案

在这种情况下,当您有这样的大型应用程序时,我想您应该可以去更多的域驱动设计方法并将上下文拆分成一些单独的,有界的上下文。这样当后来的开发人员向程序添加功能时,他们将被限制为只能根据他们将在那里使用哪些上下文访问某些表。



为了更好的信息,朱莉莱曼最近出来了一个关于企业实体框架的Pluralsight课程真的很好。她在本网站。这是一个非常好的课程,我强烈推荐它,特别是对于你似乎在做什么。


So the problem I am trying to solve is this; We are using Entity Framework to access our Oracle database that has 1200-1500 tables. Now mind you we are not accessing them all, but possibly could have 800+ to access. We are using the UnitOfWork --> Repository --> Service pattern and that works great, but we are trying to figure out if we should have one big DbContext, or multiple little contexts that are specific to the task at hand.

Our UnitOfWork is setup using an EFUnitOfWorkBase like so:

public abstract class EFUnitOfWorkBase : IUnitOfWork
{
    private bool isDisposed = false;

    public DbContextBase Context { get; set; }

    protected EFUnitOfWorkBase(DbContextBase context)
    {
        Context = context;
    }

    public int Commit()
    {
        return Context.SaveChanges();
    }

    public void Dispose()
    {
        if (!isDisposed)
            Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
        isDisposed = true;
        if (disposing)
        {
            if (this.Context != null)
                this.Context.Dispose();
        }
    }

    public IRepository<TEntity> GetRepository<TEntity>() where TEntity : Common.EntityBase<TEntity>
    {
        return new Repository<TEntity>(this);
    }
}

Any unit of work we create extends that base one and provides the context like so:

public class EmployeeDirectoryUnitOfWork : EFUnitOfWorkBase
{
    public EmployeeDirectoryUnitOfWork(string connectionString)
        : base(new EmployeeDirectoryContext(connectionString))
    {
    }
}

The DbContext is passed a connection string through the unit of work.

The Repository looks like this:

public abstract class RepositoryBase<TEntity> : IRepository<TEntity> where TEntity : class
{
    protected DbContextBase Context;
    protected DbSet<TEntity> EntitySet;

    public RepositoryBase(EFUnitOfWorkBase unitOfWork)
    {
        Enforce.ArgumentNotNull(unitOfWork, "unitOfWork");

        Context = unitOfWork.Context;
        EntitySet = Context.Set<TEntity>();
    }

    public TEntity Add(TEntity entity)
    {
        Enforce.ArgumentNotNull(entity, "entity");

        return EntitySet.Add(entity);
    }

    public TEntity Attach(TEntity entity)
    {
        Enforce.ArgumentNotNull(entity, "entity");

        return EntitySet.Attach(entity);
    }

    public TEntity Delete(TEntity entity)
    {
        Enforce.ArgumentNotNull(entity, "entity");

        return EntitySet.Remove(entity);
    }

    public System.Linq.IQueryable<TEntity> Query()
    {
        return EntitySet.AsQueryable();
    }

    public TEntity Save(TEntity entity)
    {
        Enforce.ArgumentNotNull(entity, "entity");

        Attach(entity);
        Context.MarkModified(entity);

        return entity;
    }
}

Any suggestions on how to best handle this situation?

解决方案

In such a case when you have a large application like this, I think you should probably go for a more Domain Driven Design approach and split the contexts into some separate, bounded contexts. This way when later developers are adding features to the program they will be confined to only being able to access certain tables depending on which context they will be using there.

For better information, Julie Lerman recently came out with a course on Pluralsight about Entity Framework in the Enterprise that's really good. She posted a small clip of it (actually about bounded contexts) on this site. It's a very good course, and I highly recommend it, especially for what you appear to be doing.

这篇关于UnitOfWork和实体框架上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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