Monday, March 7, 2016

A generic C# data access layer built on top of the Entity Framework

The Entity Framework is the Microsoft official ORM (Object-Relational Mapping) framework.


This library implements the Repository Pattern. It's mask the detail of the Data Access Logic from the Business Logic using Repositories.
Repositories are build on top of Entities using C# generics.
Repositories offers a few methods to perform CRUD operations (Create, Read, Update, Delete) and other SQL operations like MAX, MIN...
An instance of the entity framewor context class is created for each operation.
Each repository implements an interface that provides methods to performs operation on an entity object of the model.
You can access any repository by the main model instance. Each repository will be instantiated at the model construction.
Any repository method can be overriden.
The main model class implements the a generic class and defines each repository as a public property.

The main methods you will find on repository are:
  • List: load an entities with records
  • Find: load an entities searching for key values
  • Add: add records to the underlying database
  • Update: update records of the underlying database
  • Remove: remove records from the underlying database
The List method filter values by the use of a predicate.
The generated LINQ query is then translated to SQL by the Entity Framework engine.
The Find method implements the Find LINQ method.
Add, Update and Remove methods perform the SQL INSERT, UPDATE and DELETE operations.

Three methods should be overridden almost every time a Repository is implemented:
  • CanAdd: check if entities can be added
  • CanUpdate: check if entities can be updated
  • CanRemove: check if entities can be removed
Those methods should be called before the main Add, Update and Remove operations to check for entites consistency.

Other SQL/LINQ operators are implemented in the repository, like:
Any, FirstOrDefault, Average, Order, Count, LongCount, Max, Min, Remove, Sum.

A LanguageHelper class provides usefull methods to internationalize String fields used in repositories. Those fields can be used to localize errors message for repository methods.

A few lines of codes are enough to implemt a fully loaded model.

This project is as always release open source. You can find source code, on the github.com link above.
The code also contains a sample model, and a few UnitTest to check against it.


Code

Notes
  • read risk disclaimer
  • excuse my bad english

4 comments:

  1. Hi David how are you? I'm using your generic repository and i'm getting an error.
    When i try to retrieve a list from a Sales object, don't retrive the relates entities, the error is:

    Property accessor 'Sales' on object threw the following exception:'The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.'

    Any ideas?.
    Basically i need to retrieve a list of entities with all related entities.

    ReplyDelete
    Replies
    1. Hello, are you using EF Database First, or Code First? Try to use Database First, it should be related to the way your entity classes have been created. Also, start working with the sample model provided, just add the tst_dgdatamodeltest database you can find in the source code, and run the unit tests. If you debug the test you can see what's happen inside. Or you can add the source folder project to your solution, and use it as source code to debug it by line and find why you get this error.

      Delete
    2. Hello Davide, thanks for your quick response.
      I use your test project to start building my own test, and the same behavior apperas.
      For example, on test TestHelperConcurrency1, you have this:

      //get post
      _posts = samplemodel.Posts.Find(_posts.posts_id);

      this works fine, but, if you try to acces to blogs property from posts, trow the exception

      System.ObjectDisposedException: 'The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.'

      The same issue that i have in my test (with other db).

      Delete
    3. That's because the blog property it's lazy loaded. You can access the blog property by the Blog repository.

      Delete