I'm creating an layered app in C# and trying to use EF 6 in it.
I want the code first approach (POCO).
My idea of layers (projects):
DAL (Entity Framework 6).
Entities (Where I have my classes that represent my tables in the DB, or entities representing my DB objects).
Business (I add via method extension methods to the Entites classes, like 'void CalculateTaxes()' to a Product class).
Presentation (UI, for now is Win Forms, later can be web...)
First, I'm relatively new to all of it and I'm studying layer architectures.
The question: The DAL layer gotta reference the Entities layer (where I have my DB objects) for creating and maintaning the DB and the Entities layer gotta reference the DAL layer to access the objects from the DB, and I cannot do this (circular dependency).
How should I procede in this scenario? For more experencied developers, is this the best approach?
Entities layer gotta see the DAL layer to access the objects from the DB
This is where you should break your dependency. The entities should be storage-agnostic. The current popular method of bridging the entities and EF is a Repository layer that encapsulates the CRUD (Create, Read, Update, Delete) logic.
Related
I'm wondering about the utility of making a dal layer with EF.
Why not calling EF directly in business layer, considering EF DBContext is a unitOfWork and List DBSet are repositories ?
So why adding an extra DAL layer, wich is finally a facade..
The only advantage i see, is in case of we have to change the data access implementation, like replace EF by Hibernate or other. But honestly, i've never seen that happen.
Actually with a data mapper the necessity of developing a DAL is plain useless because it would contain 0 lines of code.
Everything on top of a data mapper isn't a data access layer but actual domain, because a data mapper implementation like an OR/M translates your objects into the underlying relational data and viceversa, and you work on top of them is to develop your domain and miss the pain of object-relational impedance.
The point of introducing the repository pattern on top of a data mapper is because you want to both be able to switch the underlying data store even to a non-relational one in the long run (also, switch from NoSQL to SQL, who knows!), and there's another definitive reason to introduce the repository layer in your software: because you want to be able to mock the data store with fakes in order to unit test your domain.
Finally, even when Entity Framework implements unit of work and other patterns, sometimes their implementation may not suit your own domain requirements and you need to wrap them to provide more concretion to your domain.
I use Entity Framework as ORM in my .net MVC project. I've implemented the Repository-Pattern (generic) to get/save/update/remove DAOs (Data Access Objects). I also have Business Objects which contain all the business logic. I have - for example - a DAO called Student and a BO (Business Object) called Student as well. The BO contains the logic, the DAO just the data stored in the DB.
Now I am wondering if the Student-Repository should return the Business-Object instead of the DAO?
I could achieve that using Automapper by converting the DAO to a Business Object before returning it from the Repository.Get(). Same with all the other methods. But is this a good practice?
Update
I have a Data Access Layer project and a project for the Business Logic. Entity Framework creates its entities in partial classes (into the Data Access Project) so I could actually extend the entities with other partial classes but the problem is that I reference the Data Access Project in my Business project and I don't have access to the logic code within the Data Access project. So I have to put the logic inside the Business project but as it is not possible to create partial classes over two projects I have to go another way... or do you have a good idea how to structure and solve the problem in a better way?
IMHO there are several goals (some competing):
Make business logic testable in isolation
Design domain objects to match your domain
Decouple data access from everything else
Keep it simple
Can you test your business logic without a database? Probably yes, whether the classes are EF POCO entities or mapped from DAOs.
Do your domain objects match your domain? Are their names well-chosen? Are they always in a valid state? (This can be difficult with a bunch of public read/write properties.) Domain-driven design considerations apply here. (I'm no expert in that.)
Could you swap out EF for Dapper, SQL Server for MongoDB, or current data access for a web service call without changing anything outside the data access layer - with confidence? My suspicion is no. Generic repositories tend to leak IQueryable into other layers. Not everything supports querying, and provider implementations vary. Unit tests typically use LINQ to Objects, which does not behave the same as LINQ to Entities. Also, if you want to extract a web service contract, you would have to look through all classes to find all the queries. See IQueryable is Tight Coupling.
Finally, do you need all of this? If your application's purpose is CRUD data access with no business logic above simple validation, maybe not. These considerations definitely apply to a complex application or site.
Yes, that's totally good practice. Usually you have repository interfaces defined in domain assembly. These interfaces are used by domain services, and implemented in persistence assembly. Entity Framework allows you to map business entities fluently, without polluting them with attributes or forcing them to inherit from some specific base class (POCO entities). That makes your domain model Persistence Ignorant.
I have a service layer which makes requests of business layers to perform some functions.
The business layers access a repository which uses Entity Framework.
The service layer has a Unit Of Work object that maintains references to the ObjectContexts of EF.
When the business layers have been called, the service layer tells the Unit of Work to save the changes which it does inside of a transaction.
This is all working fine, I'm able to have multiple repositories talking to multiple edmx files all in a transaction.
One of the rules in the system is that the EF stuff has to stay the repository layer (apart from the Contexts in the UoW).
But my design has a major flaw.
In a function in the business layer I want to call a respository function to create a new record in the database. Then, in the same function in the business layer, i want to point another record at the new record. The EF entity isn't available to the business layer and because it hasn't returned to the service layer yet I don't have an id for the new record which I could then update the other record with.
Any suggestions on how I should change my design to support this?
Following the desing proposed here MVC3 and Entity Framework, I'm trying to create different layers for DAL, BL and web, using MVC4 + EntitiFramework5.
Quote from #Davide Piras
1 - ProjectName.Interfaces (Class library, entities's interfaces);
2 - ProjectName.DAL (Class library, the only one allowed to even know the EF is used, the POCO entities implement the interfaces of project 1 using another file where you redeclare same objects using partial classes...);
3 - ProjectName.BL (Class library, Business logic, references the two projects above 1 and 2);
4 - ProjectName.Web (ASP.NET MVC application, Presentation Layer, references two projects 1 and 3 but NOT 2);
I have a doubt on the connection between BL and DAL. DAL knows EF, BL shoudln't .. but how to implement it? I mean, I created the classes that represent my entitis on both the layers (and this seems a bit a duplication to me .. even if in BL I'll add validation and other sutff), but how I expose the database values to BL?
in the default MVC4 solution I have
DbSet<Entity> entity
that I can query (.Find, etc) .. I suppose I need to map them in my BL (IQueryable? IEnumerable? Isomething??)
compltely confused .. any helps is appreciate
The lines can become a little blurred when you speak of DAL and EF. In some cases you could consider EF the DAL. But I usually do not have the the BL access EF directly and abstract it to a higher level, so that you could easily swap out EF as your ORM if need be. I use the Repository Design Pattern to further abstract EF. The other advantage to this pattern is that it makes it easier to unit test and you can use dependency injection. I also use the Unit of Work Design Pattern to handle transactions in the system. So are the Repository and the Unit of Work part of the DAL or is it just EF. That is probably debatable and I know longer concern myself with trying to define the DAL. Here are the layers I would recommend using in an MVC 4 project.
The Application or Domain Layer is your BL Layer. I tend to incorporate concepts used in the Service Layer in this layer as I have not seen any benefit yet in separating it out. But there is the option of adding this layer on the top also.
No, the Business Logic layer needs to know about the DAL because it needs to call methods on the DAL in order to retrieve/update/add data (only using the Interfaces, it shouldn't be allowed to see the POCO classes). The BL doesn't know anything about EF (which is as it should be, incase you ever wanted to replace EF with something else).
So, for example to add a new record:
User adds the new details and submits the form
Web project calls AddItems in the BL layer (using a list of objects that are the interface)
BL project has some business logic, additional validation before passing the list of objects to the DAL (also has the error handling too maybe)
DAL creates the items in the database, then, if required, passes a list of the interface back
we have a classical 3-tier-architecture application. Now we face a little problem and we don't know the best way to handle it.
In the last layer (database-layer) we have a POCO-class, that gets filled with data from a database. In the top layer we have a MVC3 asp.net web-application. The MVC application would work best, if it could just read the POCO-class.
But as the GUI-layer cannot access the database-layer directly, it cannot get the exact same class.
What is the best way to get a POCO-class from the last layer to the top layer?
The actual issue is that your entities should not be defined in the data layer. Data layer, as well as any other layer in your app, might get completely rewritten one day, and you don't want entities themselves to be tied to any of these layers.
In other words, define your entities in a separate project, and then reference it from all other projects:
- Entities
- Data access layer
+ references Entities
- Business layer
+ references DAL
+ references Entities
- Presentation layer
+ references BL
+ references Entities
The same goes for repository interfaces: if you are using a repository pattern to abstract your data access, Entities project is the one which should contain all repository interfaces, which can then be implemented by a specific DAL choice.
You can create a project of DTOs that is referenced from all the different layer projects. This way you can share the DTO POCOs between all the layers of your application.