【发布时间】:2012-11-26 22:21:35
【问题描述】:
在我的 ASP.NET MVC 4 项目中,我仔细遵循了这个实现存储库和工作单元示例中的设计原则。
我对这篇文章的评论特别感兴趣,是在展示了通用存储库之后写的:
这个通用存储库将处理典型的 CRUD 需求。当特定实体类型有特殊要求时,例如更复杂的过滤或排序,您可以创建一个派生类,该类具有该类型的其他方法。
由于我的应用遇到了这种特殊情况,我尝试这样做。我做了一个 GenericRepository 和文章中的一样,还有一个 SharedContext 类(SharedContext 正是文章中的 UnitOfWork 类,但这个名字对我来说更有意义)
通用存储库:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace BusinessLogicLayer.Repositories
{
public class GenericRepository<T> where T: class
{
internal DbSet<T> _dbSet;
internal DBConnection _context;
#region constructors
public GenericRepository(SharedContext ctx)
{
_context = ctx.Context;
}
public GenericRepository(DBConnection context)
{
_context = context;
_dbSet = context.Set<T>();
}
#endregion
}
}
SharedContext(工作单元)类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace BusinessLogicLayer.Repositories
{
public class SharedContext : IDisposable
{
#region repositories
private GenericRepository<Entities.Customer> _customerRepository;
/// <summary>
/// access the Customer entity
/// </summary>
public GenericRepository<Entities.Customer> CustomerRepository
{
get
{
if (_customerRepository == null)
_customerRepository = new GenericRepository<Entities.Customer>(_context);
return _customerRepository;
}
}
#endregion
#region context management
private Entities.DBConnection _context = new Entities.DBConnection();
internal Entities.DBConnection Context { get { return _context; } }
//other methods - save, delete
#endregion
}
}
现在问题来了:注意我是如何暴露上面的 Context 属性的——我怀疑这是否真的是有意的,我觉得我这样做是在打破这种模式。我非常喜欢在相同的上下文中通过存储库控制一切的想法,但是我需要一些通用存储库不提供的其他方法 - 所以我创建了一个单独的 CustomerRepository:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
namespace BusinessLogicLayer.Repositories
{
public class CustomerRepository: GenericRepository<Entities.Customer>
{
public CustomerRepository(SharedContext ctx)
: base(ctx)
{ }
public decimal GetCustomerBonusByFrequency()
{
//
}
}
}
...在我的控制器类中,我这样使用:
private SharedContext ctx = new SharedContext();
public PartialViewResult CustomerBonus()
{
CustomerRepository cRepo = new CustomerRepository(ctx);
var bonus = cRepo.GetCustomerBonusByFrequency();
return PartialView(bonus);
}
所以我的两个问题是:
-
列表项
这是文章中提到的添加额外功能的预期方式吗?我指的是 CustomRepository 类,这对我来说感觉像是一种模式的破坏,因为已经有一种方法可以让客户通过 GenericRepository(我不再使用),而且我正在公开上下文。
-
如果这很糟糕,那么我应该如何正确地做到这一点?我只需要为我的客户实体提供额外的方法,但要以尊重模式的方式。
谢谢,
编辑:
我需要在 SharedContext 中公开 Context 属性,因为如果我删除 GenericRepository 中的构造函数(采用 SharedContext)和 CustomerRepository 类中的 :base(ctx),我会得到:
BusinessLogicLayer.DBModel.Customer 不包含采用 0 个参数的构造函数
【问题讨论】:
标签: c# entity-framework c#-4.0 repository-pattern unit-of-work