【问题标题】:Entity Framework with a layered web application具有分层 Web 应用程序的实体框架
【发布时间】:2014-02-13 23:56:47
【问题描述】:

我知道这个问题似乎已经在这里提出了,但是我有具体的疑问,主要是数据库优先使用,并且在回答的问题中缺少代码示例。

我有这些层:核心、数据和 UI (asp.net mvc)。 我在 MSSQL 中有这些表:Person 和 Contact。

问题 1:在数据层,EDMX 生成 Person 和 Data POCO。我在哪里写像 SearchPersonByCity() 这样的方法?我是否需要在同一数据层中创建另一个 Person 类,仅用于写入数据 CRUD?我怎么做这个?请举个例子(类、命名空间等。不需要整个实际代码)

问题 2:如何在数据层和核心(域模型)之间转换这些数据?我需要在核心(域)类中在哪里创建相同的SearchPersonByCity()?也许只是为这些数据访问方法在核心层创建另一个 Person 类?

请给我一些代码示例,以及大公司在现实生活中的表现,因为它似乎很愚蠢,需要维护大量代码,并且很可能我出错了。

我并不懒惰,我阅读了数百页的 Entity Framework 书籍,这里有问题,我无法弄清楚如何在代码中做到这一点。

【问题讨论】:

    标签: c# asp.net entity-framework orm architecture


    【解决方案1】:

    在我看来,我会在你的情况下使用存储库模式,所以首先你定义了一个 IRepository 类:

    public interface IRepository<T> where T : 
    {
        void Add(T entity);
        void Update(T entity);
        void Delete(T entity);
        void Delete(Expression<Func<T, bool>> where);
        T GetById(long id);
        T GetById(string id);
        T Get(Expression<Func<T, bool>> where);
    }
    

    还有一个抽象基 RepositoryBase 类:

    public abstract class RepositoryBase<T> where T : class
    {
        private PersonDBEntities dataContext;
        private readonly IDbSet<T> dbset;
        protected RepositoryBase(IDatabaseFactory databaseFactory)
        {
            DatabaseFactory = databaseFactory;
            dbset = DataContext.Set<T>();
        }
    
        protected IDatabaseFactory DatabaseFactory
        {
            get;
            private set;
        }
    
        protected PersonDBEntities DataContext
        {
            get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
        }
        public virtual void Add(T entity)
        {
            dbset.Add(entity);
        }
        public virtual void Update(T entity)
        {
            dbset.Attach(entity);
            dataContext.Entry(entity).State = EntityState.Modified;
        }
        public virtual void Delete(T entity)
        {
            dbset.Remove(entity);
        }
        public virtual void Delete(Expression<Func<T, bool>> where)
        {
            IEnumerable<T> objects = dbset.Where<T>(where).AsEnumerable();
            foreach (T obj in objects)
            dbset.Remove(obj);
        }
        public virtual T GetById(long id)
        {
            return dbset.Find(id);
        }
        public virtual T GetById(string id)
        {
            return dbset.Find(id);
        }
        public virtual IEnumerable<T> GetAll()
        {
            return dbset.ToList();
        }
    
        //You can return IQueryable if you want to build your expression true later on...
        public virtual IEnumerable<T> Get(Expression<Func<T, bool>> where)
        {
            return dbset.Where(where).ToList();
        }
    }
    

    还有你的 PersonRepository 类:

    public class PersonRepository: RepositoryBase<Person>, IPersonRepository
        {
        public PersonRepository(IDatabaseFactory databaseFactory)
            : base(databaseFactory)
            {
            }           
        }
    public interface IPersonRepository : IRepository<Person> // Person will be your POCO class
    {
    }
    

    下一步是在您的服务层上,您将定义并实现实际的 SearchPersonByCity() 方法:

    public class PersonService : IPersonService
    {
        private readonly IPersonRepository personRepository;
        private readonly IUnitOfWork unitOfWork;
    
        public PersonService(IPersonRepository personRepository, IUnitOfWork unitOfWork)
        {
            this.personRepository = personRepository;
            this.unitOfWork = unitOfWork;
        }
    
        public IEnumerable<Person> SearchPersonByCity(string city)
        {
            var persons = personRepository.Get(p => p.City == city);
            return persons;
        }
    }
    

    【讨论】:

    • 但有一件事。我的 EDMX 在 Repository 层,对吧?因此,作为您在服务层工作的 POCO Person 类。 UI 层(asp.net mvc)会访问这些 Repository 自动生成的数据实体吗?
    • Repositories 对象将与您的 EDMX 实体模型对象位于同一层。 EDMX 是您的 dbcontext。您的 Repository 基类将包含 dbcontext 的一个实例。您可以将 POCO 类放在域模型层中。 UI 层 (mvc) 只能访问作为包装层的服务层来调用您的存储库方法。
    • “你可以把你的 POCO 类放在域模型层”怎么样?在您的代码示例中,您将 DATA-MODEL 返回给服务,它会在 UI 中使用 DATA-MODEL,这是错误的。它应该返回域模型或视图模型以在 UI 中工作,对吗?那么,会怎么样呢?
    • 是的,您可以这样做,但在我看来,这有点过度架构。 POCO 类也可以用作您的业务对象。您可能想要添加您的 Person POCO 类的业务对象,并在 SearchPersonByCity 方法中,将 POCO Person 类映射到您的业务 Person 类,改为返回 IEnumerable
    猜你喜欢
    • 2014-12-10
    • 2011-03-19
    • 2012-05-15
    • 1970-01-01
    • 2015-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多