Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有分层web应用程序的实体框架_C#_Asp.net_Entity Framework_Orm_Architecture - Fatal编程技术网

C# 具有分层web应用程序的实体框架

C# 具有分层web应用程序的实体框架,c#,asp.net,entity-framework,orm,architecture,C#,Asp.net,Entity Framework,Orm,Architecture,我知道这个问题似乎已经在这里提出了,但我有具体的疑问,主要是在数据库第一次使用方面,并且在回答的问题中缺少代码示例 我有以下几层:核心层、数据层和UI层(asp.NETMVC)。 我在MSSQL中有这些表:Person和Contact 问题1:在数据层中,EDMX生成Person和数据POCO。我在哪里编写方法,比如SearchPersonByCity()?我是否需要在同一数据层中创建另一个Person类,仅用于写入数据CRUD?我是怎么做的?请举例说明(类、名称空间等,不需要整个实际代码) 问

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

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

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

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

请给我一些代码示例,以及大公司在现实生活中是如何做的,因为它看起来很愚蠢,有很多代码让mantain和Probliby感到困惑,我有点做错了


我并不懒惰,我阅读了数百页的实体框架书籍和这里的问题,我不知道如何在代码中做到这一点。

在我看来,我会在您的案例中使用存储库模式,因此首先定义一个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);
}
公共接口i假设,其中T:
{
无效添加(T实体);
无效更新(T实体);
无效删除(T实体);
作废删除(如有);
T GetById(长id);
T GetById(字符串id);
T Get(表达式在何处);
}
和一个抽象的基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();
    }
}
公共抽象类RepositoryBase,其中T:class
{
个人背景;
专用只读IDbSet数据库集;
受保护的RepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory=DatabaseFactory;
dbset=DataContext.Set();
}
受保护的IDatabaseFactory数据库工厂
{
得到;
私人设置;
}
受保护的个人条件数据上下文
{
获取{return dataContext???(dataContext=DatabaseFactory.get());}
}
公共虚拟空添加(T实体)
{
添加(实体);
}
公共虚拟无效更新(T实体)
{
附加数据集(实体);
dataContext.Entry(entity).State=EntityState.Modified;
}
公共虚拟作废删除(T实体)
{
删除(实体);
}
公共虚拟void Delete(表达式where)
{
IEnumerable objects=dbset.Where(Where).AsEnumerable();
foreach(对象中的对象)
dbset.Remove(obj);
}
公共虚拟T GetById(长id)
{
返回dbset.Find(id);
}
公共虚拟T GetById(字符串id)
{
返回dbset.Find(id);
}
公共虚拟IEnumerable GetAll()
{
返回dbset.ToList();
}
//如果以后要构建表达式true,可以返回IQueryable。。。
公共虚拟IEnumerable Get(表达式where)
{
返回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
{
}
公共类PersonRepository:RepositoryBase,IPersonRepository { 公共PersonRepository(IDatabaseFactory databaseFactory) :base(数据库工厂) { } } 公共接口IPersonRepository:IRepository//Person将是您的POCO类 { } 下一步是在服务层,您将定义并实现实际的SearchPersonByCity()方法:

公共类PersonService:IPersonService
{
私有只读IPersonRepository personRepository;
私有只读IUnitOfWork;
公共人员服务(IPersonRepository personRepository,IUnitOfWork unitOfWork)
{
this.personRepository=personRepository;
this.unitOfWork=unitOfWork;
}
公共IEnumerable SearchPersonByCity(字符串城市)
{
var persons=personRepository.Get(p=>p.City==City);
返回人员;
}
}

但有一件事。我的EDMX在存储库层,对吗?所以作为您在服务层工作的POCO Person类。UI层(asp.net mvc)将访问这些存储库的自动生成数据实体?存储库对象将与EDMX实体模型对象位于同一层。EDMX是您的dbcontext。您的存储库基类将包含dbcontext的实例。您可以将POCO类放在域模型层中。UI层(mvc)只能访问服务层,服务层是调用存储库方法的包装层?在您的代码示例中,您将数据模型返回到服务,而它将在UI中使用数据模型,这是错误的。它应该返回域模型或视图模型以在UI中工作,对吗?那么,这将是怎样的呢?是的,你可以这样做,但在我看来,这有点过于建筑学了。POCO类可以作为业务对象使用。您可能希望添加Person POCO类的业务对象,并在SearchPersonByCity方法中,将POCO Person类映射到business Person类,而返回IEnumerable。
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;
    }
}