编辑:
我认为通用存储库是反模式。但我不明白@TomTom 的评论。
原答案:
正如 Radim Köhler 提到的,您需要实施Repository and Unit of Work patterns
但我认为他提供的文章并不完全正确。
在我目前的工作中,我使用以下这些模式的实现。例如,我们有三种类型的实体:Person, Good and Order
. 我为 Persons 创建了存储库。在常见情况下,存储库不能是通用的。它必须包含代表该实体的特定查询的方法。因此,通过查看存储库的界面,您可以了解对实体(例如人)执行了哪些类型的查询。正如您将看到的,我为名为 的 Person 创建了 DTO PersonWrap
。要从 Person 创建 PersonWrap 并从 PersonWrap 更新 Person,您可以使用 AutoMapper 而不是PersonWrap()
构造函数和Update()
方法。因为 EntityFrameworkDbContext
实现了Unit of Work
模式,您只需将创建的 DbContext 提供给存储库方法。如果存储库方法是一个单独的操作,并且您不需要此方法之外的 DbContext,您可以在此方法中创建和处置它。
public class Person {
public int Id { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public DateTime RegistrationDate { get; set; }
public List<Order> Orders { get; set; }
}
public class Good {
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
public class Order {
public int Id { get; set; }
public Person Person { get; set; }
public Good Good { get; set; }
public int Count { get; set; }
}
public class MyDbContext: DbContext
{
public IDbSet<Person> Persons { get { return Set<Person>(); }}
public IDbSet<Good> Goods { get { return Set<Good>(); }}
public IDbSet<Order> Orders { get { return Set<Order>(); }}
}
public class PersonRepository {
public IEnumerable<Person> GetAll() {
using (var context = new MyDbContext()) {
return context.Persons.ToList();
}
}
public IEnumerable<Person> GetLastWeekPersons() {
using (var context = new MyDbContext()) {
return context.Persons.Where(p => p.RegistrationDate > new DateTime().AddDays(-7)).ToList();
}
}
public Person GetById(int id, MyDbContext context) {
return context.Persons.Include(p => p.Orders).FirstOrDefault(p => p.Id == id);
}
public Person GetById(int id) {
using (var context = new MyDbContext()) {
return GetById(id, context);
}
}
}
public class PersonWrap {
public int Id { get; set; }
public string FirstName { get; set; }
public string SecondName { get; set; }
public int OrderCount { get; set; }
public PersonWrap(Person person) {
Id = person.Id;
FirstName = person.FirstName;
SecondName = person.SecondName;
OrderCount = person.Orders.Count;
}
public void Update(Person person) {
person.FirstName = FirstName;
person.SecondName = SecondName;
}
}
public class PersonDetailsViewController {
public PersonWrap Person { get; protected set; }
public PersonDetailsViewController(int personId) {
var person = new PersonRepository().GetById(personId);
if (person != null) {
Person = new PersonWrap(person);
}
}
public void Save() {
using (var context = new MyDbContext()) {
var person = new PersonRepository().GetById(Person.Id, context);
Person.Update(person);
context.SaveChanges();
}
}
}