设置 EF 应用程序的结构

发布于 2024-11-27 19:40:04 字数 2080 浏览 0 评论 0原文

我正在使用 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)我创建了一个

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

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

关于如何让这个设计听起来有什么建议吗?我应该就这样离开吗?执行此操作时我通常应该添加或避免什么?

I'm working on a prototype EF application, using POCOs. Mainly as an introduction to the framework I'm wondering about a good way to set up the application in a nice structure. Later on I'm planning to incorporate WCF into it.

What I've done is the following:

1) I created an edmx file, but with the Code Generation Property set to None and generated my database schema,

2) I created the POCOs which all look like:

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

The interface looks like this:

public interface IPocoContext
{
    IObjectSet<Person> Persons { get; }

    int Save();
}

4) Lastly I created a repository, implementing an 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);

}

Now, when I get on playing around with this, this design dictates me to instantiate a repository every time I want to fetch or mutate some data, like this:

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

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

Somehow this just feels wrong and flawed, on the other hand, 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.

Any tips on how to make this design sound? Should I leave it this way? Any things I should add or avoid in general when doing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

苏佲洛 2024-12-04 19:40:04

我不明白这部分:

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

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

如果调用存储库构造函数而不将上下文作为参数传递,为什么要在外部范围中创建上下文?使用多个上下文只会让事情变得更加困难。另外,如果您的外部块仅创建该类的实例,那么为存储库创建接口并尝试隐藏它有什么意义呢?

你的做法正确吗?一般来说是的。您应该使用单一上下文进行逻辑操作(工作单元)并且如果您的存储库通过构造函数获取上下文,您需要为每个上下文创建一组新的存储库。这通常是通过依赖注入来实现的。

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

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

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

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

顺便提一句。 您想要什么价值从使用存储库中获取?

I don't understand this part:

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

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

Why are you creating the context in outer scope if you call repository constructor without passing the context as parameter? Using multiple contexts will make things only much harder. Also what is the point of making the interface for repository and trying to hide it if your outer block will just create instance of the class?

Is your approach correct? Generally yes. You should use single context for logical operation (unit of work) and if your repository gets context through constructor you need to create a new set of repositories for each context. This is usually achieved through dependency injection.

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.

Well this can be solved pretty easily by lazy initialization:

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

But I would not put this into context itself. I would probably use this in some data access factory because it should be outside of the context and passing single factory as injection to classes / methods using multiple repositories is simpler.

Btw. what value will you get from using repository?

薄情伤 2024-12-04 19:40:04

如果您使用 POCO 创建数据库模型,可以尝试 EF Code First 吗?恕我直言,使用 Code First 比在设计器中创建 EDMX 模型更清晰。

If you use POCO to create model of your database, maeby try EF Code First? IMHO using Code First is more clearly than creating EDMX model in designer.

三人与歌 2024-12-04 19:40:04

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

Use Dependency Injection using any container like Castle Windsor, AutoFac , etc by providing per request Object Context.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文