原文 Generic repository pattern and Unit of work with Entity framework

Repository pattern is an abstraction layer between your business logic layer and data access layer. This abstract layer contains methods to server data from data layer to business layer. Now, changes in your data layer cannot affect the business layer directly.

For more information about repository pattern or unit of work visit this article. Below is my approach how to implement repository pattern and unit of work with entity framework.

1. Create IGenericRepository interface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public interface IGenericRepository<TEntity>
{
    /// <summary>
    /// Get all entities from db
    /// </summary>
    /// <param name="filter"></param>
    /// <param name="orderBy"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    List<TEntity> Get(
        Expression<Func<TEntity, bool>> filter = null,
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
        params Expression<Func<TEntity, object>>[] includes);
 
    /// <summary>
    /// Get query for entity
    /// </summary>
    /// <param name="filter"></param>
    /// <param name="orderBy"></param>
    /// <returns></returns>
    IQueryable<TEntity> Query(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null);
 
    /// <summary>
    /// Get single entity by primary key
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    TEntity GetById(object id);
 
    /// <summary>
    /// Get first or default entity by filter
    /// </summary>
    /// <param name="filter"></param>
    /// <param name="includes"></param>
    /// <returns></returns>
    TEntity GetFirstOrDefault(
        Expression<Func<TEntity, bool>> filter = null,
        params Expression<Func<TEntity, object>>[] includes);
 
    /// <summary>
    /// Insert entity to db
    /// </summary>
    /// <param name="entity"></param>
    void Insert(TEntity entity);
 
    /// <summary>
    /// Update entity in db
    /// </summary>
    /// <param name="entity"></param>
    void Update(TEntity entity);
 
    /// <summary>
    /// Delete entity from db by primary key
    /// </summary>
    /// <param name="id"></param>
    void Delete(object id);
}

2. Create GenericRepository class to implement interface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
    private DbContext context;
    private DbSet<TEntity> dbSet;
 
    public GenericRepository(DbContext context)
    {
        this.context = context;
        this.dbSet = context.Set<TEntity>();
    }
 
    public virtual List<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, params Expression<Func<TEntity, object>>[] includes)
    {
        IQueryable<TEntity> query = dbSet;
 
        foreach (Expression<Func<TEntity, object>> include in includes)
            query = query.Include(include);
 
        if (filter != null)
            query = query.Where(filter);
 
        if (orderBy != null)
            query = orderBy(query);
 
        return query.ToList();
    }
 
    public virtual IQueryable<TEntity> Query(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null)
    {
        IQueryable<TEntity> query = dbSet;
 
        if (filter != null)
            query = query.Where(filter);
 
        if (orderBy != null)
            query = orderBy(query);
 
        return query;
    }
 
    public virtual TEntity GetById(object id)
    {
        return dbSet.Find(id);
    }
 
    public virtual TEntity GetFirstOrDefault(Expression<Func<TEntity, bool>> filter = null, params Expression<Func<TEntity, object>>[] includes)
    {
        IQueryable<TEntity> query = dbSet;
 
        foreach (Expression<Func<TEntity, object>> include in includes)
            query = query.Include(include);
 
        return query.FirstOrDefault(filter);
    }
 
    public virtual void Insert(TEntity entity)
    {
        dbSet.Add(entity);
    }
 
    public virtual void Update(TEntity entity)
    {
        dbSet.Attach(entity);
        context.Entry(entity).State = EntityState.Modified;
    }
 
    public virtual void Delete(object id)
    {
        TEntity entityToDelete = dbSet.Find(id);
        if (context.Entry(entityToDelete).State == EntityState.Detached)
        {
            dbSet.Attach(entityToDelete);
        }
        dbSet.Remove(entityToDelete);
    }
}

3. Create IUnitOfWork interface

1
2
3
4
5
public interface IUnitOfWork
{
    IGenericRepository<Model> ModelRepository { get; }
    void Save();
}

4. Create UnitOfWork class to implement interface

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class UnitOfWork : IUnitOfWork, System.IDisposable
{
    private readonly MyDatabaseContext _context;
    private IGenericRepository<Model> _modelRepository;
 
    public UnitOfWork(MyDatabaseContext context)
    {
        _context = context;
    }
 
    public IGenericRepository<Model> ModelRepository
    {
        get { return _modelRepository ?? (_modelRepository = new GenericRepository<Model>(_context)); }
    }
 
    public void Save()
    {
        _context.SaveChanges();
    }
 
    private bool disposed = false;
 
    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposed)
        {
            if (disposing)
            {
                _context.Dispose();
            }
        }
        this.disposed = true;
    }
 
    public void Dispose()
    {
        Dispose(true);
        System.GC.SuppressFinalize(this);
    }
}

5. Usage in controller

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class HomeController : Controller
{
    private IUnitOfWork _unitOfWork;
 
    public HomeController(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }
 
    //
    // GET: /Home/
 
    public ActionResult Index()
    {
        // get all models (all properties)
        List<Model> modelList = _unitOfWork.ModelRepository.Get(m => m.FirstName == "Jan" || m.LastName == "Holinka", includeProperties: "Account");
 
        // get all models (some properties)
        List<ModelDto> modelDtoList = _unitOfWork.UserRepository
            .Query(x => x.FirstName == "Jan" || x.LastName == "Holinka")
            .Select(x => new ModelDto
            {
                FirstName = x.FirstName,
                LastName = x.LastName
            })
            .ToList();
 
            return View("Index");
        }
 
        // show list of models in view
        return View(modelList);
    }
}
 
public class ModelDto
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

That's all.

最新文章

  1. Heap堆的理解以及在IAR中如何设置堆的大小
  2. Fiddler-2 Fiddler抓包原理
  3. 100怎么变成100.00 || undefined在数字环境下是:NaN || null在数字环境下是0 || 数组的toString()方法把每个元素变成字符串,拼在一起以逗号隔开 || 空数组转换成字符串后是什么?
  4. Java语言中,类所拥有的“孩子”,他们的关系是怎样的
  5. C# Reflection BindingFlags
  6. 十个JavaScript中易犯的小错误,你中了几枪?
  7. hdu City Game
  8. linux C(hello world)三个数最大和三个数最新
  9. Project Management - 2) Estimate Your Work
  10. jQuery技术内幕电子版5
  11. 30种mysql优化sql语句查询的方法&lt;转&gt;
  12. oracle group by 使用
  13. poj2000---和1969一样的模板
  14. ZED 相机 &amp;&amp; ORB-SLAM2安装环境配置与ROS下的调试
  15. ZOJ-2750 Idiomatic Phrases Game---Dijk最短路
  16. 【爬虫】Xpath高级用法
  17. new Thread与线程创建
  18. PHP规范PSR0和PSR4的理解
  19. Enable Scribble,Enable Guard Edges,Enable Guard Malloc,Zombie Objects
  20. Expectation Propagation: Theory and Application

热门文章

  1. objdump的使用方法和 symbol table的每列的含义
  2. js原型链与继承(初体验)
  3. mapreduce 实现pagerank
  4. 首页视频播放jquery
  5. ASP.NET MVC +EasyUI 权限设计(四)角色动作
  6. github客户端创建仓库
  7. 使用ASP.NET注册工具aspnet_regiis.exe注册IIS
  8. Daily Scrum 11.11
  9. 【转】jquery-取消冒泡
  10. SQL Server数据库事务日志序列号(LSN)介绍