4

I am googling this issue now for weeks, but cannot find a good discussion. It boils down to this: As POCO entities used in a dbContext are in fact a definition of the database, shouldn't they be constrained to the Data Access Layer and not be visible outside it?

On the other hand: it is convenient to hide some POCO entities in the ViewModels. so that changed properties can be passed back easily to the Data Access Layer.

I find many examples of Entities that make their way into the user interface, but also many examples of where AutoMapper is used to map the properties of a ViewModel to an Entity.

Can someone point me to some good working examples or discussions that could help me make a well informed choice?

closed as too broad by Robert Harvey, gbjbaanb, gnat, user40980, GlenH7 Feb 11 '14 at 15:36

Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. Avoid asking multiple distinct questions at once. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • Don't the higher layers typically have access to classes that implement the entity interfaces, not necessarily the entities themselves? – user16764 Feb 10 '14 at 16:21
  • 1
    Based on the answers your question is attracting, I have voted to close this question as too broad. It seems that is why you can't find relevant information on Google; perhaps you should shore up your information about application architecture, and then come to the table with some more specific questions. – Robert Harvey Feb 10 '14 at 16:26
6

Here is one rule of thumb (but don't follow it blindly! Understand why you must use it!) for the direction that your dependencies must follow

Always depend in the direction of abstraction and stability

What that mean is that the dependencies that everyone depend on must be dependencies that change the less. Everyone depend on them, thus they're costly to change. So design those dependencies to have little to no reason to change!

And one way to do that is to make those dependencies mostly of unimplemented interface and stupid data structure that serve only to transfer information between objects. Then, more opinionated module, like the UI and the Data Access layer, and various part of the business logic, implements those interface with big fat objects that actually do the work. This is called the Dependency inversion principle.

Now, the direction that the arrow of the layers must take depend on who your talking to: "UI must depend on business logic which depend on the data access! No! The business logic must be in the center and everyone depends on it!" Lots of opinions and religion, but its all futile in the end. What matter is the abstraction. If your dependencies is through abstract elements, then you have it. The rest is pure pointless intellectual debate.


So, to answer your question, I'm gonna ask you another one "What are the reason for your so-called entity to change?" You have the answer in your own question :

As POCO entities used in a dbContext are in fact a definition of the database

If your entity are a definition of the database, that mean they will change everytime the database change. And if they must conform to a dbContext, that mean they have a strong coupling to the Entity Framework. If Microsoft decide to change the way EF work, your entities will have to change. Your entities will not be the nice little abstractions that you need to minimize coupling.

So yes, in that case, if you want to consider them a model of the database, then you should hide them away in a persistence layer, and make sure that nobody ever see them that don't also know about the database.

In summary, if you want an application that is well decoupled and strongly cohesive, no, they should not be depended upon by everyone, because if you do, everyone will depend transitively on the database structure. So everytime the database change, the whole application will have to change and it will be a pain. The way people usually cope with that is to make the database not change, and that introduce a lot of rigidity in your data storage. At some point or the other the database will need to change, and you will have to pay a hefty price of technical debt at that point.


The above was as neutral as I can make it, the rest will be more opinionated. Feel free to ignore it if it don't fit your views.

Your entities should be the base of your application and everyone should depend on them. They should not, never, be an implementation of the database. The entity framework job is to bend around your entity, and if he can't do that, then it's not the framework for you: ditch it as soon as you can. He shouldn't have any power over your entity. YOU decide how your entities are structured. Don't buy into the promise of magic that the conceptor demos are showing you. At one point or the other you will need to do something unexpected, all the magic will disappear, and you will have to leave your nice dreamy world and write the code you really needed from the start.

Try to make your entities an abstraction of your domain model (which is much less likely to change), and at that point, everyone will be able to depend on them, and your database will be free to be implemented however you want. You will have less magic at first and you will code more, but in the long shot, you will win on all account.

2

To properly answer this you have to consider 2 aspects: the entities themselves and the DB connection.

Naturally the DB connection should only be accessible from the data access layer, so you have a reduced surface to interact with the DB.

The entities that come from there though... obviously if you're retrieving a read-only entity and passing around like a plain old data object, then there's no problem, so ahead and use them knowing that you're just bypassing the pain of creating a whole alternative layer of objects that exist to pass the entity data across tiers. I mean, you could create a new class to send data to the presentation tier, and the logic tier could take the data from the entity and populate this new class... but generally why bother when you can just pass the entity itself and save yourself a heap of trouble and performance problems copying data.

However, it gets more interesting when you need to pass data back. Here you either have persistent entities that need to be specially marshalled as special objects (ie that contain enough information to remind the DB what they are and where they came from). This starts to make things messy, and while its easy to just pass the entity about, update its fields and pass it back up the tiers to the DB, you might as well open up access to your DB to the client in that case! Here I would try to make updates occur via special methods on your logic tier that call up into the DB to modify these. This also stops the problem where you modify an entity down on the client and fail to persist it back to the DB - you can end up with a modified entity that you use, not realising that its been orphaned by other activity.

That last bit is the most important part to understand - if you use entities through your layers, you will have to pass them up and down the stack like a complex client-server model, or your data integrity can become compromised.

So all in all, I would prefer to keep the entities in the DB layer.

  • Instead of this general hand waving, let's get specific. Say I have a Customer table, a DAL that hands me a Customer object, and a repository class that allows me to look up customers. Can I use that customer object from the repository directly, or do I have to convert it to some sort of faux customer object before I can use it? How many layers does your application actually have, and at what point does it turn from a Customer object to a CustomerView object and back? – Robert Harvey Feb 10 '14 at 16:35
  • it is a bit vague wasn't it.. I was trying to ignore my manager at the time. In short- if you're not going to edit the Customer object, go ahead and pass it about, saves time and effort in creating a CustomerView object that just replicates the Customer object (but this might depend on your situation). But I would prefer methods that update the data tier directly, instead of editing the Customer object and sending it all the way back up the chain. The problem with passing the entity about is that you are introducing a dependency onto it that ties you to your schema. – gbjbaanb Feb 10 '14 at 16:36
  • In ASP.NET MVC, for example, the passing about of domain objects would end at the Controller method, which is the access point for the repository objects. Normally, you would then convert it to a ViewModel object for display, unless it was pure CRUD. An invoice, for example, requires displaying more than just a Customer object, and sometimes you just need one or two fields from that customer object. So all of that translation between objects happens in the Controller method. – Robert Harvey Feb 10 '14 at 16:41
  • he never mentioned any particular technology stack - could be some java stuff for example. My usual approach to this is to expose data as stored procedures, so the "show invoice x" would return all the required data pre-translated. – gbjbaanb Feb 10 '14 at 16:44
  • True, but that's partly why I voted to close his question as too broad. Without focusing on a particular technology or architecture, the question is also hand-waving. – Robert Harvey Feb 10 '14 at 16:46
-1

I am googling this issue now for weeks, but cannot find a good discussion. It boils down to this: As POCO entities used in a dbContext are in fact a definition of the database, shouldn't they be constrained to the Data Access Layer and not be visible outside it?

This is a complete misunderstanding of the purpose of object relational mappers and domain driven design. What you want is persistence ignorance. You shouldn't model a database definition but the objects of your problem-domain and how they relate to and interact with each other. You shouldn't worry about persistence at all when you design your problem domain, unless you're trying to fight performance problems e.g.

Entities are most definitely a cross cutting concern and it is perfetcly fine to use them in every layer of the application. However, if you want to limit the modification of an entity to a certain module, you can hide the entities within the module and only publish DTO objects that are readonly to consumers outside of the module. But within the module, every layer can be allowed to work with the entity.

On the other hand: it is convenient to hide some POCO entities in the ViewModels. so that changed properties can be passed back easily to the Data Access Layer.

Yes it is, and if you don't do it like that, you'll bloat the code unecessarily and end up with a lasagna antipattern in the worst case.

  • 3
    Can you address the implied concern in his question, which is "How do I avoid tight coupling?" Your "persistence ignorance" argument doesn't seem compelling; while some ORM's (like EF) do allow the back end data store to be swapped out, in practice this hardly ever happens. Back in the day, we actually designed real databases around the problem domain, before people started doing "class-first" design. The database-first approach actually works quite well, and has the virtue of having best practices designed into the data store from the start. – Robert Harvey Feb 10 '14 at 16:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.