原文 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.

Generic repository pattern and Unit of work with Entity framework的更多相关文章

  1. Using the Repository Pattern with ASP.NET MVC and Entity Framework

    原文:http://www.codeguru.com/csharp/.net/net_asp/mvc/using-the-repository-pattern-with-asp.net-mvc-and ...

  2. [转]Using the Repository Pattern with ASP.NET MVC and Entity Framework

    本文转自:http://www.codeguru.com/csharp/.net/net_asp/mvc/using-the-repository-pattern-with-asp.net-mvc-a ...

  3. Follow me to learn what is repository pattern

    Introduction Creating a generic repository pattern in an mvc application with entity framework is th ...

  4. [转]Upgrading to Async with Entity Framework, MVC, OData AsyncEntitySetController, Kendo UI, Glimpse & Generic Unit of Work Repository Framework v2.0

    本文转自:http://www.tuicool.com/articles/BBVr6z Thanks to everyone for allowing us to give back to the . ...

  5. Asp.net webform scaffolding结合Generic Unit of Work & (Extensible) Repositories Framework代码生成向导

    Asp.net webform scaffolding结合Generic Unit of Work & (Extensible) Repositories Framework代码生成向导 在上 ...

  6. Using Repository Pattern in Entity Framework

    One of the most common pattern is followed in the world of Entity Framework is “Repository Pattern”. ...

  7. Laravel与Repository Pattern(仓库模式)

    为什么要学习Repository Pattern(仓库模式) Repository 模式主要思想是建立一个数据操作代理层,把controller里的数据操作剥离出来,这样做有几个好处: 把数据处理逻辑 ...

  8. 在Entity Framework 4.0中使用 Repository 和 Unit of Work 模式

    [原文地址]Using Repository and Unit of Work patterns with Entity Framework 4.0 [原文发表日期] 16 June 09 04:08 ...

  9. Using StructureMap DI and Generic Repository

    In this post, i will show how to use generic repository and dependency injection using structuremap. ...

随机推荐

  1. Webserver issues | PHP manager for IIS

    4 down vote accepted In order to successfully install the PHP manager for IIS 8, you need the .NET 3 ...

  2. 精美舒适的对话消息提示框--第三方开源--SweetAlertDialog

    SweetAlertDialog(sweet-alert-dialog)是一个套制作精美.动画效果出色生动的Android对话.消息提示框 SweetAlertDialog(sweet-alert-d ...

  3. 创建SQL数据库指定文件路径

    create database b2c on  primary  -- 默认就属于primary文件组,可省略(/*--数据文件的具体描述--*/    name='b2c',  -- 主数据文件的逻 ...

  4. WPF学习笔记 控件篇 属性整理【1】FrameworkElement

    最近在做WPF方面的内容,由于好多属性不太了解,经常想当然的设置,经常出现自己未意料的问题,所以感觉得梳理下. ps:先补下常用控件的类结构,免得乱了 .NET Framework 4.5 Using ...

  5. EditPlus64的安装配置

    下载地址,直接到360下载即可,下载完毕之后,进入如下网址,完后在线生成注册码 http://www.jb51.net/tools/editplus/ 以上是文本编辑器EditPlus的安装以及注册, ...

  6. centos Supervisor

    Supervisor是一个进程监控程序. 满足的需求是:我现在有一个进程需要每时每刻不断的跑,但是这个进程又有可能由于各种原因有可能中断.当进程中断的时候我希望能自动重新启动它,此时,我就需要使用到了 ...

  7. ASP.NET Web - 回送

    如果希望把更改事件立即传送给服务器,可以把AutoPostback属性设置为true.这样就会使用客户端的JavaScript把窗体数据立即提交给服务器.当然,网络通信量也会增加.使用这个功能时要小心 ...

  8. Ado.Net实现简易(省、市、县)三级联动查询,还附加Access数据

    小弟在博客园驻园不久,初来咋到:将最近写的小程序附上,希望各位大牛们吐槽:激发对程序员围观的童鞋们,赶紧加入IT行业,如果你在上海那简称就是SHIT,哈哈题外话,以下开始切入正题: 坐公交车是旁边偶遇 ...

  9. 【转】在RedHat上搭建自己Email服务器

    原文:http://6839976.blog.51cto.com/6829976/1323482 by LN__@linux 目前邮件服务器中,想要拥有自己的邮件服务器,单单使用senmail,pos ...

  10. 【POJ】【2987】Firing

    网络流/最大权闭合子图 胡伯涛论文里有讲…… sigh……细节处理太伤心了,先是count和ans输出弄反了,改过来顺序时又忘了必须先算出来ans!要是不执行一下Dinic的话count就无意义了…… ...