1

Im a bit confused about what is best practice when working with Entity Framework and ASP.NET Web API.

I am working on a project that contains a iOS/Android app and an API the app will use to communicate with.

For now the project is seperated like this:

  • Project.Core (This project contains all database access like DbContext, Entity models, services that controls the logic of the system and the services will only return mapped models. The Entity models will never be exposed from this project)

  • Project.Models (This project contains all the mapped models that the app and API uses)

  • Project.Api (Contains all API controllers, actions and authorization logic. This project will use the Project.Core services to execute the desired action and will only work with the mapped models)

Now my question is:

  1. Is it bad practice not to use the Entity Framework models and DbContext directly in the API project?

  2. Is it bad practice to hide the Entity Framework models and DbContext from all other projects except the Project.Core?

My idea was to isolate all database related logic in a seperate project.

2 Answers 2

1

This is just my opinion, but I feel like I disagree with Ewan in some ways.

I think it depends.

I think I definitely wouldn't be returning the EF objects to your client. I would use a package like AutoMapper or whatever to map them to DTO objects that is used only for transporting data to and from client.

However, I don't think it's necessarily bad practice to call EF directly from your API layer.

For unit testing, I don't see why you can't just test the controller methods with the EF queries in there using the in-memory database. I find from experience it's much more useful than just mocking it - cause a lot of the time, if you have unexpected behaviour it'll be in your LINQ query.

The thing is EF already implements a Generic Repository pattern - that's basically what each DbSet object is. In addition, it has the best interface - because it uses LINQ which every .NET developer already knows even if they've never used EF.

I think it's about common sense. If it's a complicated query - sure, put it inside a service or introduce another repository layer. But I see too many people re-implementing EF's repository pattern and I feel it's unnecessary and makes it somewhat worst - because you're essentially now making a custom interface instead of a standard LINQ query.

2
  • Thank you for your opinion. Its very nice to have something to compare with. I will think about doing the mapping directly in the api controller instead of doing it inside the service classes in Project.Core project. :)
    – Martin C
    Commented Aug 15, 2019 at 8:40
  • I would agree with you on the "re-implementing EF's repository pattern" and the "if you have unexpected behaviour it'll be in your LINQ query". Unfortunately I have found that using an in memory DB causes things to run differently to using the real db. So you get tests which pass, but fail in production.
    – Ewan
    Commented Aug 15, 2019 at 9:23
1

Best practice is to hide the EF stuff.

This allows you to share you models without forcing the EF dependency, maintain a separate data layer, run unit tests etc etc

You can do this by mapping the EF generated to your models, or by using code first models if you don't end up having to add attributes to them.

I would add an extra Project.Repository to contain all DB related stuff

3
  • Thank you for the quick response. I am using code first with ForeignKey, Key, Required attributes. You would add an extra Project.Repository to contain all the Entity Framework models, DbContext and would you add the database quey logic to that project too? :-)
    – Martin C
    Commented Aug 15, 2019 at 8:08
  • yup. repo.GetProduct("productA") repo.AddUser(user) etc etc
    – Ewan
    Commented Aug 15, 2019 at 8:11
  • Thank you for the quick answers. :)
    – Martin C
    Commented Aug 15, 2019 at 8:15

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.