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。不管怎样,这个