简体   繁体   中英

Entity Framework with a layered web application

I know that this question seems to be already made here, but I have specific doubts, mainly in database-first usage and lack of code-example in replied questions.

I have these layers: Core, Data and UI (asp.net mvc). I have these tables in MSSQL: Person and Contact.

Question 1: In data layer, EDMX generates Person and Data POCO. Where I write methods like SearchPersonByCity() ? Do I need to create another Person class in the same data layer, just for writting data CRUD? How I make this? Please make an example (classes, namespaces, etc.. not necessary the whole actual code)

Question 2: How do I transpose these data between data-layer and core (domain models)? Where do I need to create the same SearchPersonByCity() in core (domain) class? Maybe create another Person class in core-layer just for these data-acess methods?

Please give me some code example, and how big companies do in real life, because it seems to be so dumb and a lot of code to mantain and problaby I'm getting something wrong.

I'm not lazy, and I read hundreds pages of Entity Framework books, questions here, and I can't figure out how to do this in code.

In my opinion I would use the repository pattern in your case, so first you have a IRepository class defined:

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

And an abstract base RepositoryBase class:

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

And your PersonRepository class:

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

Next step is on your service layer, you will define and implement that actual SearchPersonByCity() method:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM