Generic repository pattern and Unit of work with Entity framework

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

时间: 2024-10-19 03:21:39

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

[转]Upgrading to Async with Entity Framework, MVC, OData AsyncEntitySetController, Kendo UI, Glimpse &amp; 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 .NET community, we released v1.0 of the Generic Unit of Work and Repository Framework for four weeks and received 655 downloads and 4121 views. This po

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

Asp.net webform scaffolding结合Generic Unit of Work & (Extensible) Repositories Framework代码生成向导 在上次发布的使用简单Repositories模式生成的代码结构有点繁琐太过复杂,而且整个项目层次结构很不清晰,在开发过程中还是出现大量的逻辑代码写在了Apsx.cs中,感觉有点不伦不类.而最近在codeplex上看到一篇<Generic Unit of Work & (Extensible) Rep

4.CRUD Operations Using the Repository Pattern in MVC【在MVC中使用仓储模式进行增删查改】

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-using-the-repository-pattern-in-mvc/ 上一篇文章,讲到了MVC中基本的增删查改,这篇文章,我会继续说到,使用仓储模式,进行增删查改. 什么是仓储模式呢,我们先来了解一下:  仓储模式是为了在程序的数据访问层和业务逻辑层之间创建一个抽象层,它是一种数据访问模式,提供了一种更松散耦合的数据访问方法.我们把创建数据访问的逻辑代码写在单独的类中,或者类库中

从Entity Framework的实现方式来看DDD中的repository仓储模式运用

一:最普通的数据库操作 static void Main(string[] args) { using (SchoolDBEntities db = new SchoolDBEntities()) { db.Students.Add(new Student() { StudentName = "nihao" }); db.SaveChanges(); } } domain 和 db 是怎么操作... DbSet<Student> 集合 [用于存放集合] 从名称中可以看出,是

Entity Framework Repository模式

Repository模式之前 如果我们用最原始的EF进行设计对每个实体类的“C(增加).R(读取).U(修改).D(删除)”这四个操作. 第一个:先来看看查询,对于实体类简单的查询操作,每次都是这样的过程会在代码中拥有大量的重复 极为类似的代码段. using (var db = new EFContext("EFContext")) { var persons = db.Persons.Where(t => t.PersonName == "aehyok")

6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pattern-and-dep/ 系列目录: Relationship in Entity Framework Using Code First Approach With Fluent API[[使用EF Code-First方式和Fluent API来探讨EF中的关系]] Code First Mig

1.Relationship in Entity Framework Using Code First Approach With Fluent API【使用EF Code-First方式和Fluent API来探讨EF中的关系】

In this article, you will learn about relationships in Entity Framework using the Code First Approach with Fluent API. 在这篇文章中,你将会学习到使用EF Code-First方式和Fluent API来探讨EF中的关系(一对一,一对多,多对多). Introduction[介绍] A relationship, in the context of databases, is a

5.在MVC中使用泛型仓储模式和工作单元来进行增删查改

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pattern-and-uni/ 系列目录: Relationship in Entity Framework Using Code First Approach With Fluent API[[使用EF Code-First方式和Fluent API来探讨EF中的关系]] Code First Mig

基于Repository模式设计项目架构—你可以参考的项目架构设计

关于Repository模式,直接百度查就可以了,其来源是<企业应用架构模式>.我们新建一个Infrastructure文件夹,这里就是基础设施部分,EF Core的上下文类以及Repository层都放在这里面.新建一个IReposotory的接口,其内容就是封装了基本的CRUD: public interface IRepository<TEntity> where TEntity : class { ///获取当前实体的查询数据集 IQueryable<TEntity&