How do you work with DDD and EF4

I'm having trouble trying to apply DDD with EF4 (in ASP MVC2 context). Your advice will be greatly appreciated.

First of all, I started using POCO because the dependency on ObjectContext was not very convenient in many situations.

Moving to POCO solved some problems, but experience is not what I'm used to with NHibernate.

I would like to know if it is possible to use the constructor and generate not only objects, but also Value objects (ComplexType?). If I mean a Value Object, this is a class with one ctor without any specified properties (do you need a T4 modification?).

The only way I found adding behavior to anonymous entities is to create partial classes that extend the ones that edmx generates. I am not satisfied with this approach.

I do not know how to create multiple repositories with one edmx. Right now I'm using partial classes to group methods for each aggregate. In fact, each group is a repository.

Last question about IQueryable. Should it be exposed outside the repository? If I refer to a book, then the repository should be a unit of execution and should not expose something like IQueryable. What do you think?

Thank you for your help.

Thomas

+6
domain-driven-design entity-framework-4
source share
3 answers

Some time has passed since I asked this question and had the opportunity to do it myself.

I do not consider it good practice to expose IQueryable altogether outside the DAL layer. This brings more problems that he solves. I am talking about large MVC applications. First of all, the reorganization is more complicated, many developers of custom IQueryable instances from views and after struggling with the fact that when IQueryable is resolved, the connection has already been established. Performance issues because the entire database is often queried for a given set of results, etc.

I rather exposed Ienumerable from my repositories and believe me, this will save me a lot of problems.

0
source share

It is good to use POCOs, but note that EntityObject does not require an ObjectContext .

Yes, complex types are value objects, and yes, they can be generated in the designer. Select several properties of the object, right-click and select refactoring to a complex type.

I highly recommend putting business methods in their own types, not on entities. Anemic types can be a problem if you have to support them, but when they are encoded, they are hardly a maintenance problem. Creating business logic separately from entity types allows your business rules and your data model to evolve independently. Yes, you should use partial classes if you have to mix these problems, but I don’t think that separating your model from your rules is bad.

I think repositories should expose IQueryable , but you can make a good example that domain services should not. People often try to create their repositories in domain services, but remember that the repository exists only for abstract preservation. Issues such as security should be in the domain services, and you can make it so that having IQueryable gives too much power to the consumer.

+4
source share

I think it’s OK to open IQueryable outside the repository, just because it cannot be unnecessarily restrictive. If you only open data using methods such as GetPeopleByBirthday and GetPeopleByLastName , what happens when someone goes looking for someone by name and birthday? Do you pull all the people with the last name "Smith" and do a linear search for the desired birthday or create a new method GetPeopleByBirthdayAndLastName ? What about the poor unfortunate person who has to implement the QBE form?

Back when the only way to make special domain queries was to create SQL, the only way to keep yourself safe is to offer only specific methods for retrieving and modifying data. Now that we have LINQ, there is no reason to keep the handcuffs on. Anyone can send a request, and you can safely fulfill it without any problems.

Of course, you may be worried that the user may view other data, but this is easy to mitigate, because you can limit the data that you issue. For example:

 public IQueryable<Content> Content { get { return Content.Where(c => c.UserId == this.UserId); } } 

This ensures that the only Content strings a user can get are those that have their UserId .

If your problem is with the database load, you can do things like check query expressions to scan tables (access tables without Where clauses or without indexed columns in the Where clause). Of course, this is not trivial, and I would not recommend it.

+1
source share

All Articles