我正在使用 POCO 开发原型(prototype) EF 应用程序。主要作为对框架的介绍,我想知道在一个好的结构中设置应用程序的好方法。稍后我打算将 WCF 合并到其中。
我所做的如下:
1) 我创建了一个 edmx 文件,但代码生成属性设置为 None 并生成了我的数据库模式,
2) 我创建的 POCO 看起来都是这样的:
public class Person
{
public Person()
{
}
public Person(string firstName, string lastName)
{
FirstName = firstName;
LastName = lastName;
}
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
3) 我创建了一个上下文
public class PocoContext : ObjectContext, IPocoContext
{
private IObjectSet<Person> persons;
public PocoContext() : base("name=PocoContainer", "PocoContainer")
{
ContextOptions.LazyLoadingEnabled = true;
persons= CreateObjectSet<Person>();
}
public IObjectSet<Person> Persons
{
get
{
return persons;
}
}
public int Save()
{
return base.SaveChanges();
}
}
界面是这样的:
public interface IPocoContext
{
IObjectSet<Person> Persons { get; }
int Save();
}
4) 最后我创建了一个存储库,实现了一个接口(interface):
public class PersonRepository : IEntityRepository<Person>
{
private IPocoContext context;
public PersonRepository()
{
context = new PocoContext();
}
public PersonRepository(IPocoContext context)
{
this.context = context;
}
// other methods from IEntityRepository<T>
}
public interface IEntityRepository<T>
{
void Add(T entity);
List<T> GetAll();
T GetById(int id);
void Delete(T entity);
}
现在,当我开始尝试这个时,这个设计要求我每次想要获取或改变一些数据时都实例化一个存储库,如下所示:
using (var context = new PocoContext())
{
PersonRepository prep = new PersonRepository();
List<Person> pers = prep.GetAll();
}
不知何故,这感觉是错误的和有缺陷的,另一方面,仅仅实例化派生上下文中的每个存储库也感觉不太好,因为可能实例化我可能根本不需要的对象。
关于如何让这个设计听起来有什么技巧吗?我应该这样离开吗?执行此操作时,一般情况下我应该添加或避免什么?
最佳答案
我不明白这部分:
using (var context = new PocoContext())
{
PersonRepository prep = new PersonRepository();
List<Person> pers = prep.GetAll();
}
如果调用存储库构造函数而不将上下文作为参数传递,为什么要在外部范围内创建上下文?使用多个上下文只会让事情变得更加困难。如果您的外部 block 只会创建该类的实例,那么为存储库创建接口(interface)并试图隐藏它的意义何在?
您的方法正确吗?一般是的。你应该使用 single context for logical operation (工作单元)并且如果您的存储库通过构造函数获取上下文,您需要为每个上下文创建一组新的存储库。这通常是通过依赖注入(inject)来实现的。
just instantiating every repository in the derived context doesn't feel too good either, because of potentially instantiating objects I might not need at all.
好吧,这可以通过惰性初始化很容易地解决:
private SomeRepositoryType _someRepository
public SomeRepositoryType SomeRepository
{
get { _someRepository ?? (_someRepository = new SomeRepositoryType(context)) }
}
但我不会把它放在上下文中。我可能会在某些数据访问工厂中使用它,因为它应该在上下文之外,并且将单个工厂作为注入(inject)传递给使用多个存储库的类/方法更简单。
顺便说一句。 what value你会从使用存储库中得到什么吗?
关于c# - 设置 EF 应用程序的结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6952466/