三、EF中的开发模式之Repository。
在实际项目中,如果希望能够对存储逻辑有一定的控制,于是就有了repository模式的出现,也就是对原始存储逻辑的一种封装。
1.在接口层中创建一个通用的存储接口IRepository,便于逻辑复用。
public interface IRepository<T> where T : class, new()
{
T Create();
T Update(T entity);
T Insert(T entity);
void Delete(T entity);
T Find(params object[] keyValues);
List<T> FindAll();
}
{
T Create();
T Update(T entity);
T Insert(T entity);
void Delete(T entity);
T Find(params object[] keyValues);
List<T> FindAll();
}
2.在DAL层中创建一个实现了IRepository接口的RepositoryBase基类,主要的就是需要提供一个DbContext,基本思想就是利用DbContext的Set构造的类型来提供封装,这里就不做多的说明了,我这里为了简单,使用了默认构造方法,FacePerfEntities是添加edmx时生成的类。
public class RepositoryBase<T> : IRepository<T> where T : class,new()
{
public DbContext context;
public RepositoryBase(DbContext _context)
{
this.context = _context;
}
public RepositoryBase()
{
this.context = new FacePerfEntities();
}
#region IRepository<T> 成员
public T Create()
{
return context.Set<T>().Create();
}
public T Update(T entity)
{
if (context.Entry<T>(entity).State == EntityState.Modified)
context.SaveChanges();
return entity;
}
public T Insert(T entity)
{
context.Set<T>().Add(entity);
context.SaveChanges();
return entity;
}
public void Delete(T entity)
{
context.Set<T>().Remove(entity);
context.SaveChanges();
}
public T Find(params object[] keyValues)
{
return context.Set<T>().Find(keyValues);
}
public List<T> FindAll()
{
return context.Set<T>().ToList();
}
#endregion
}
{
public DbContext context;
public RepositoryBase(DbContext _context)
{
this.context = _context;
}
public RepositoryBase()
{
this.context = new FacePerfEntities();
}
#region IRepository<T> 成员
public T Create()
{
return context.Set<T>().Create();
}
public T Update(T entity)
{
if (context.Entry<T>(entity).State == EntityState.Modified)
context.SaveChanges();
return entity;
}
public T Insert(T entity)
{
context.Set<T>().Add(entity);
context.SaveChanges();
return entity;
}
public void Delete(T entity)
{
context.Set<T>().Remove(entity);
context.SaveChanges();
}
public T Find(params object[] keyValues)
{
return context.Set<T>().Find(keyValues);
}
public List<T> FindAll()
{
return context.Set<T>().ToList();
}
#endregion
}
3.在接口层中创建一个关于员工的接口:IEmployeeRepository
public interface IEmployeeRepository<T>
{
List<T> SearchEmployee();
}
{
List<T> SearchEmployee();
}
4:在业务逻辑层中创建关于员工的专用类:EmployeeRepositoryBLL。
public class EmployeeRepositoryBLL : IEmployeeRepository<Employee>
{
EmployeeRepository repository = new EmployeeRepository();
public List<Employee> SearchEmployee()
{
return repository.FindAll();
}
}
{
EmployeeRepository repository = new EmployeeRepository();
public List<Employee> SearchEmployee()
{
return repository.FindAll();
}
}
5:在服务层中创建员工的服务类,由于这只是测试用,所以服务类起的作用并不明显,至于为什么有服务层,是为了将UI层与业务逻辑层分离等等众多原因。
public class EmployeeRepositoryService
{
EmployeeRepositoryBLL repositoryEmployee=null ;
public EmployeeRepositoryService()
{
repositoryEmployee = new EmployeeRepositoryBLL();
}
public List<Employee> SearchEmployee()
{
return this.repositoryEmployee.SearchEmployee();
}
}
{
EmployeeRepositoryBLL repositoryEmployee=null ;
public EmployeeRepositoryService()
{
repositoryEmployee = new EmployeeRepositoryBLL();
}
public List<Employee> SearchEmployee()
{
return this.repositoryEmployee.SearchEmployee();
}
}
6:最后就是UI了。
static void Main(string[] args)
{
EmployeeRepositoryService ers = new EmployeeRepositoryService();
var list = ers.SearchEmployee();
var people = from p in list
orderby p.CreatedOn
select p;
Console.WriteLine("All People:");
foreach (var person in people)
{
Console.WriteLine("- {0}", person.ChineseName);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
{
EmployeeRepositoryService ers = new EmployeeRepositoryService();
var list = ers.SearchEmployee();
var people = from p in list
orderby p.CreatedOn
select p;
Console.WriteLine("All People:");
foreach (var person in people)
{
Console.WriteLine("- {0}", person.ChineseName);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
补充说明:
1.添加完edmx后,以及完成添加代码生成项后,查询PersonModel.Context.cs,代码如下:
public FacePerfEntities()
: base("name=FacePerfEntities")
{
}
: base("name=FacePerfEntities")
{
}
构造函数中的参数FacePerfEntities,其实就对应EF数据库连接串的节点名称。
2.添加完edmx后,在DAL层还会有一个packages.config文件,这个文件不用发布到UI程序下面,也不影响程序运行,只需要将连接串对应的节点复制到UI配置文件中即可。
总结: 经过上面的改造,已经越来越适合实际项目了,EF在不断改进,我想在一些小型项目中快速开发倒是蛮适合的。