如何通过工作单元访问上下文中的方法?

How to access a method in the context through unit of work?

如果我有以下上下文:

public partial class HRMainDataCTX : DbContext
{
    public HRMainDataCTX()
        : base("name=HRMainDataCTX")
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

  //DbSets
    public virtual int SEARCHEMPLOYEE(Nullable<decimal> p_EMP_NUM, string p_EMP_NAME)
    {
        var p_EMP_NUMParameter = p_EMP_NUM.HasValue ?
            new ObjectParameter("P_EMP_NUM", p_EMP_NUM) :
            new ObjectParameter("P_EMP_NUM", typeof(decimal));

        var p_EMP_NAMEParameter = p_EMP_NAME != null ?
            new ObjectParameter("P_EMP_NAME", p_EMP_NAME) :
            new ObjectParameter("P_EMP_NAME", typeof(string));

        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("SEARCHEMPLOYEE", p_EMP_NUMParameter, p_EMP_NAMEParameter);
    }
}

现在我像这样实现工作单元:

public class HRCTX : IDisposable
{
    private readonly HRMainDataCTX _context;

    public HRCTX()
    {
        _context = new HRMainDataCTX();
    }

    public HRCTX(HRMainDataCTX context)
    {
        _context = context;
    }
    public int Save()
    {
        return _context.SaveChanges();
    }

    public HRMainDataCTX Context
    {
        get { return _context; }
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

我不知道如何在我后面的代码中通过 UOW 访问方法(存储过程)SEARCHEMPLOYEE

好吧,在您的情况下,您只需将此方法的另一个 "Proxy-Method" 添加到您的 HRCTX 代理/UOW class,或者 - 因为 HRCTX 提供对它的底层上下文——直接在这样的上下文中调用它:

HRCTX uow = new HRCTX(someContext);
uow.Context.SEARCHEMPLOYEE(123, "123");

但我还想强调 DbContext 已经代表了一个工作单元模式(与存储库模式相结合,see here)。你基本上是在为你的上下文创建一个代理,据我在这个例子中所见 - 没有增加更多的好处或功能,所以我建议至少考虑直接使用你的 HRMainDataCTX 并可能获得去掉 HRCTX class.

如果要封装 DbContext 和业务逻辑,您可能需要将存储库与工作单元模式一起实施。 (As suggested in the AspNet guidelines)

以通用方式,您的工作单元可以像这样处理存储库:

public class HRCTX : IDisposable
{
    private readonly HRMainDataCTX _context;
    private Dictionary<Type, object> Repositories { get; set; }


    public HRCTX()
    {
        _context = new HRMainDataCTX();
        this.Repositories = new Dictionary<Type, object>();
    }


    //Get and add a repository to the dictionary if ot does not exist
    public IRepository<TEntity> GetNonGenericRepository<TEntity, TRepository>() where TEntity : class
    {
        if (this.Repositories.Keys.Contains(typeof(TRepository)))
        {
            return this.Repositories[typeof(TRepository)] as IRepository<TEntity>;
        }
        var repoType = typeof(TRepository);
        var constructorInfo = repoType.GetConstructor(new Type[] { typeof(DbContext)});
        IRepository<TEntity> repository = (IRepository<TEntity>) constructorInfo.Invoke(new object[] { this._context});
        this.Repositories.Add(typeof(TRepository), repository);
        return repository;
    }

 public IRepository<TEntity> GetGenericRepository<TEntity>() where TEntity :     class
    {
        if (this.Repositories.Keys.Contains(typeof(TEntity)))
        {
            return this.Repositories[typeof(TEntity)] as IRepository<TEntity>;
        }

        IRepository<TEntity> repository = new Repository<TEntity>(this._context);
        this.Repositories.Add(typeof(TEntity), repository);
        return repository;
    }


}

您的存储库的接口和基础 class:

 public interface IRepository<TEntity> where TEntity : class
{
    TEntity Find(Expression<Func<TEntity, bool>> match);
}

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
    protected DbContext Context { get; set; }

    public Repository(DbContext context)
    {
       this.Context = context;
    }
    public TEntity Find(Expression<Func<TEntity, bool>> match)
    {
        return Context.Set<TEntity>().SingleOrDefault(match);
    }
}

现在是您明确封装业务逻辑的部分:

public class EmployeeRepository : Repository<Employee>
{

    public EmployeeRepository(DbContext context) : base(context) {

    }
    public override Employee Find(Expression<Func<TEntity, bool>> match)
    {
        // You can either use the base class method or implement your custom logic
    }

    //This is where you encapsulate your business logic
     public Employee FindSpecific(Nullable<decimal> employeeNum, string employeeName){
         return this.Context.SEARCHEMPLOYEE(employeeNum, employeeName);
     }
}

然后您可以使用您的工作单元以域驱动设计方式访问您的业务逻辑。

HRCTX unitOfWork= new HRCTX(dbContext);
unitOfWork.GetNonGenericRepository<Employee, EmployeeRepository>().FindSpecific(1337,"1337");

对于您期望的答案来说似乎太多了,但我认为如果您不想直接公开 DbContext/Dal,则需要以这种方式构建您的应用程序。

希望对您有所帮助!

此网页详细记录了如何实现您的目标。

http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application