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

C# 如何通过工作单元访问上下文中的方法?,c#,asp.net,entity-framework,design-patterns,unit-of-work,C#,Asp.net,Entity Framework,Design Patterns,Unit Of Work,如果我有以下背景: public partial class HRMainDataCTX : DbContext { public HRMainDataCTX() : base("name=HRMainDataCTX") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { throw new UnintentionalCode

如果我有以下背景:

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


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

好吧,在您的情况下,您只需将此方法的另一个“代理方法”添加到
HRCTX
代理/UOW类中,或者-因为
HRCTX
提供了对其底层上下文的访问-直接在上下文中调用它,如下所示:

HRCTX uow = new HRCTX(someContext);
uow.Context.SEARCHEMPLOYEE(123, "123");
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;
    }


}

但我还想强调的是,
DbContext
已经代表了一种工作单元模式(与存储库模式相结合)。您基本上是在为您的上下文创建一个代理,就我在本例中看到的情况而言,它不会增加更多的好处或功能,因此,我建议至少考虑直接使用
HRMainDataCTX
,并可能去掉
HRCTX
类。

如果要封装DbContext和业务逻辑,可能需要将存储库与工作单元模式一起实现。()

以一般方式,您的工作单元可以处理如下存储库:

HRCTX uow = new HRCTX(someContext);
uow.Context.SEARCHEMPLOYEE(123, "123");
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;
    }


}
公共类HRCTX:IDisposable
{
私有只读hrmaindactx_上下文;
专用词典存储库{get;set;}
公共HRCTX()
{
_context=new HRMainDataCTX();
this.Repositories=newdictionary();
}
//如果ot不存在,则获取存储库并将其添加到字典中
public IRepository GetNonGenericRepository(),其中tenty:class
{
if(this.Repositories.Keys.Contains(typeof(TRepository)))
{
将此.Repositories[typeof(TRepository)]作为IRepository返回;
}
var repoType=类型(TRepository);
var constructorInfo=repoType.GetConstructor(新类型[]{typeof(DbContext)});
IRepository repository=(IRepository)constructorInfo.Invoke(新对象[]{this.\u context});
添加(typeof(TRepository),repository);
返回存储库;
}
public IRepository GetGenericRepository(),其中tenty:class
{
if(this.Repositories.Keys.Contains(typeof(tenty)))
{
将此.Repositories[typeof(tenty)]作为IRepository返回;
}
IRepository repository=新存储库(此.\u上下文);
添加(typeof(tenty),repository);
返回存储库;
}
}
存储库的接口和基类:

 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);
    }
}
公共接口假定,其中tenty:class
{
tenty-Find(表达式匹配);
}
公共类存储库:IRepository,其中tenty:class
{
受保护的DbContext上下文{get;set;}
公共存储库(DbContext上下文)
{
this.Context=Context;
}
公共TEntity查找(表达式匹配)
{
返回Context.Set().SingleOrDefault(匹配);
}
}
现在是清晰封装业务逻辑的部分:

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);
     }
}
公共类EmployeeRepository:存储库
{
public EmployeeRepository(DbContext上下文):基础(上下文){
}
公共覆盖员工查找(表达式匹配)
{
//您可以使用基类方法,也可以实现自定义逻辑
}
//这就是封装业务逻辑的地方
public Employee FindSpecific(可空employeeNum,字符串employeeName){
返回this.Context.SEARCHEMPLOYEE(employeeNum,employeeName);
}
}
然后,您可以使用您的工作单元以领域驱动的设计方式访问您的业务逻辑

HRCTX unitOfWork= new HRCTX(dbContext);
unitOfWork.GetNonGenericRepository<Employee, EmployeeRepository>().FindSpecific(1337,"1337");
hrctxunitofwork=newhrctx(dbContext);
GetNonGenericRepository().FindSpecific(1337,“1337”);
对于您所期望的答案来说,这似乎太多了,但我认为如果您不想直接公开DbContext/Dal,您需要以这种方式构建应用程序


希望有帮助

此网页准确记录了如何实现您的目标


您的问题不清楚,赏金公司无法帮助我们回答您的问题is@Evk当前位置你能写下关于我的问题有哪些特别不清楚的地方吗!下面我来举例说明。你没有评论bassfader的回答。因此,如果它不能回答您的问题,您能否澄清原因?关于您实际上不需要任何包装器,这是有道理的,因为DbContext已经遵循了工作单元模式。@AnynameDonotcare-我同意EvK,也同意bassfader下面的答案。此外,您还应该显示实际使用UoW代码的代码,以便说明无法访问您创建的方法的原因。@Evk我为我的问题添加了一个悬赏,以便获得更多的答案和想法。将(repo&UoW)与EF结合使用在DbContext-->UoW&DbSets-->存储库中有很多争论。。我以前在SOF上问过这个问题。我的问题非常具体,关于如何在我的代码隐藏中通过UOW访问DbContext中的方法。然后我必须添加对我的DAL.dll的引用来访问上下文,这使得
UOW
无意义
类型在未引用的程序集中定义。您必须添加引用
一个
HRCTX
类公共构造函数将
hrmaindactx
作为参数,因此您已经需要引用DAL.dll。我同意@bassfader:仅凭您提供的代码,我看不出直接使用DbContext有什么优势。这两种建议的方法是我能想到的唯一替代方法。我想包装我的
dbcontext
,这样就不需要在UI应用程序中添加对
EF
DAL
的引用。(围绕我的dbcontext的抽象层)这不是您所拥有的。。。如果您想抽象掉一些东西,您需要在不同的库中定义抽象,并且只添加对该库的引用。该库不应该提到dbContext,即使在构造函数参数中,任何公共的东西都应该不知道dbContext。不管怎样,这个