我想从独家技术的角度重新表述这个问题。
通常,通用基础存储库类包含 Add、Delete、Update、GetById 和 GetAll 方法。
现在我很想在这个基类中放置更多方法,比如 EntityExists 等......当我需要更具体的东西时,我必须深入研究 IQueryable.GetAll() 方法,我可以将谓词组合/附加到 GetAll 方法. 这应该可以节省我从技术方面看到的大量类和接口。
但是当我采用这种方法时,对我的程序有什么负面影响?
我想从独家技术的角度重新表述这个问题。
通常,通用基础存储库类包含 Add、Delete、Update、GetById 和 GetAll 方法。
现在我很想在这个基类中放置更多方法,比如 EntityExists 等......当我需要更具体的东西时,我必须深入研究 IQueryable.GetAll() 方法,我可以将谓词组合/附加到 GetAll 方法. 这应该可以节省我从技术方面看到的大量类和接口。
但是当我采用这种方法时,对我的程序有什么负面影响?
基类不是瑞士军刀或实用类。SOLID 原则也适用于他们。
对于存储库,您可以采用两种方式。第一个是使用规范模式,您对所有实体使用相同的存储库类。相反,您要做的是创建可以在查询时组合或单独使用的小型规范类。例子:
repository.Query(new FindLockedUsers(new Paging(1, 50));
其中FindLockedUsers
和Paging
是两个规范(内部类是AND
:ed)。实现是一种装饰器模式。
另一种方法是为每个实体(根聚合)使用特定的存储库。这些按实体定制的 get 方法,例如:
repository.FindLockedUsers(int pageNumber, int pageSize);
我个人更喜欢后者,因为它使合同更容易遵循(即我只需要阅读存储库接口/类即可了解如何使用它)。
通用基础存储库类应该只实现对所有可能扩展它的存储库有意义的方法。如果您有不会违反任何 SOLID 原则的此类方法的示例,我会说随时添加到此基类中。
如果没有更具体的示例(代码),我认为我无法提供比这更多的指导。
如果您遵循 OOP 原则,我会说您可以随心所欲。通常我有一个接口来声明我需要我的 EfDb 类来实现的所有内容。这样,我的控制器只能与我的界面对话,而不能直接访问我的 EfBd 类。请参见下面的示例:
界面
public interface IDataSource
{
//Person Entities
IQueryable<Person> Persons{ get; }
void SavePerson(Person person);
}
EfDb 类
//Person
public DbSet<Person> Persons { get; set; }
IQueryable<Person> IDataSource.Persons
{
get { return Persons; }
}
public void SavePerson(Person person)
{
using (var context = new EFootballDb())
{
if (person.PersonId == 0)
{
context.Persons.Add(player);
}
else if (person.PersonId > 0)
{
var currentPerson = context.Persons
.Single(p => p.PersonId == person.PersonId);
context.Entry(currentPerson ).CurrentValues.SetValues(person);
}
context.SaveChanges();
}
}
然后在您的控制器中,您只需像这样调用您的界面,并可能实现您的创建操作,如下所示。
public class PersonController : Controller
{
private readonly IDataSource _dataSource;
public PersonController(IDataSource dataSource)
{
_dataSource = dataSource;
}
[HttpGet]
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(Person model)
{
try
{
if (ModelState.IsValid)
{
_dataSource.SavePerson(model);
return RedirectToAction("Index", "Home");
}
}
catch (Exception)
{
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists, see your system administrator.");
}
return View(model);
}
我希望这会有所帮助,很抱歉长时间的演示,但只要您遵循某种软件设计原则,例如面向对象编程(OOP),一切都应该没问题。这一切都取决于您对其他类隐藏您的实现的程度。就像在我的演示中一样,控制器类无法访问我的 EfDb 类。