设置EF应用程序的结构

时间:2011-08-05 06:47:25

标签: c# .net entity-framework architecture structure

我正在使用POCO开发原型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)我创建了一个Context

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)最后我创建了一个存储库,实现了一个接口:

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();
}

不知何故,这只是感觉错误和缺陷,另一方面,只是实例化派生上下文中的每个存储库也不会感觉太好,因为可能实例化我可能根本不需要的对象。

有关如何使此设计听起来的任何提示?我应该这样离开吗?这样做时我应该添加或避免的任何事情?

3 个答案:

答案 0 :(得分:2)

我不明白这一部分:

using (var context = new PocoContext())
{   
    PersonRepository prep = new PersonRepository();

    List<Person> pers = prep.GetAll();
}

如果在不将上下文作为参数传递的情况下调用存储库构造函数,为什么要在外部作用域中创建上下文?使用多个上下文会使事情变得更加艰难。如果您的外部块只是创建类的实例,那么为存储库创建接口并尝试隐藏它的重点是什么?

你的方法是否正确?一般是的。您应该使用single context for logical operation(工作单元),如果您的存储库通过构造函数获取上下文,则需要为每个上下文创建一组新的存储库。这通常是通过依赖注入来实现的。

  

只是实例化派生上下文中的每个存储库都没有   感觉太好了,因为我可能会实例化对象   可能根本不需要。

这可以通过延迟初始化很容易解决:

private SomeRepositoryType _someRepository
public SomeRepositoryType SomeRepository
{
    get { _someRepository ?? (_someRepository = new SomeRepositoryType(context)) }
}

但我不会把它放在上下文中。我可能会在一些数据访问工厂中使用它,因为它应该在上下文之外并且将单个工厂作为注入传递给使用多个存储库的类/方法更简单。

顺便说一下。你会从使用存储库获得what value吗?

答案 1 :(得分:1)

如果您使用POCO创建数据库模型,maeby会尝试使用EF Code First吗?使用Code First的恕我直言比在设计师中创建EDMX模型更清楚。

答案 2 :(得分:0)

通过提供每个请求的对象上下文,使用Castle Windsor,AutoFac等任何容器来使用依赖注入。