views:

201

answers:

5

I am working on a project using entity framework. Is it okay to use partial classes of the EF generated classes as the business layer. I am begining to think that this is how EF is intended to be used.

I have attempted to use a DTO pattern and soon realized that i am just creating a bunch of mapping classes that is duplicating my effort and also a cause for more maintenance work and an additional layer.

I want to use self-tracking-entities and pass the EF entities to all the layers. Please share your thoughts and ideas. Thanks

A: 

I wouldn't do that. Try too keep the layers independent as possible. So a tiny change in your database schema will not affect all your layers.

Entities can be used for data layer but they should not. If at all, provide interfaces to be used and let your entities implement them (on the partial file) the BL should not know the entities but the interfaces.

Itay
I understand the concept of loose coupling and keeping the layers independent of each other. I feel that it is easier said then done. If the entities generated by the EF cannot be used in other layers, what is the better approach? Can you please provide some clear guidance.. thanks
samsur
I edited my answer
Itay
A: 

I think partial class will be a good idea. If the model is regenerated then you will not loose the business logic in the partial classes.

As an alternative you can also look into EF4 Code only so that you don't need to generate your model from the database.

Amitabh
+1  A: 

I would not do that, for the following reasons:

  1. You loose the clear distinction between the data layer and the business layer
  2. It makes the business layer more difficult to test

However, if you have some data model specific code, place that is a partial class to avoid it being lost when you regenerate the model.

Shiraz Bhaiji
So what do you propose is the correct way to create a business layer? Use the DTO pattern? Use repository?
samsur
A: 

I would use partial classes. There is no such thing as data layer in DDD-ish code. There is a data tier and it resides on SQL Server. The application code should only contain business layer and some mappings which allow persisting business objects in the mentioned data tier.

Entity Framework is you data access code so you shouldn't built your own. In most cases the database schema would be modified because the model have changed, not the opposite.

That being said, I would discourage you to share your entities in all the layers. I value separation of UI and domain layer. I would use DTO to transfer data in and out of the domain. If I have the necessary freedom, I would even use CQRS pattern to get rid of mapping entities to DTO -- I would simply create a second EF data access project meant only for reading data for the UI. It would be built on top of the same database. You read data through read (anemic -- without business logic) model, but you modify it by issuing commands that are executed against real model implemented using EF and partial methods.

Does this answer your question?

Szymon Pobiega
A: 

I had a look at using partial classes and found that exposing the database model up towards the UI layer would be restrictive.

For a few reasons:

  1. The entity model created includes a deep relational object model which depending on your schema would get exposed to the UI layer (say the presenter of MVP or the ViewModel in MVVM).
  2. The Business logic layer typically exposes operations that you can code against. If you see a save method on the BLL and look at the parameters needed to do the save and see a model that require the construction of other entities (cause of the relational nature the entity model) just to do the save, it is not keeping the operation simple.
  3. If you have a bunch of web services then the extra data will need to be sent across for no apparent gain.
  4. You can create more immutable DTO's for your operations parameters rather than encountering side effects cause the same instance was modified in some other part of the application.
  5. If you do TDD and follow YAGNI then you will tend to have a structure specifically designed for the operation you are writing, which would be easier to construct tests against (not requiring to create other objects not realated to the test just because they are on the model). In this case you might have...

    public class Order { ... pubic Guid CustomerID { get; set; } ... }

Instead of using the Entity model generated by the EF which have references exposed...

public class Order
{ ...
    pubic Customer Customer { get; set; }
... }

This way the id of the customer is only needed for an operation that takes an order. Why would you need to construct a Customer (and potentially other objects as well) for an operation that is concerned with taking orders.

If you are worried about the duplication and mapping then have a look at Automapper

aqwert