It seems to me that almost by default all code first POCO's should have private setters for their primary key a.k.a. auto-generated Id.
Like this -
public int id { get; private set; }
Is this an incorrect assumption? I do not want my API to allow setting of an auto-generated column.
Exposing a public setter should not be an issue since it is unadvised to even expose this POCO outside the Data Access Object layer..
Exposing a POCO decorated with a specific framework's attributes, or even a POCO which discloses some kind of information regarding storage (Entity Relational Database, in this instance) is a bad practice.
Consider wrapping it in an interface and returning it as an instance of that interface. This way you get to enjoy the best of both worlds. Exposing the properties which are necessary and allowing to set only a part of them.
In any case, I do not think that EF will like the private setter thing too much.
Related
When implementing DDD aggregates I usually have them expose methods that represent business functions and then those functions are responsible for modifying internal state. E.g.
public class Order
{
public int Id { get; private set; }
public IEnumerable<LineItem> LineItems { get; private set; }
public void AddLineItem(...) {...}
public void Ship() {...}
public void Cancel() {...}
}
When using EF6 or NHibernate this works well because the context/session can detect all insertions/deletes/updates of child entities. However, with EF7 I need to explicitly instruct the change tracker about such changes. E.g. when AddLineItem() adds a new line item to the LineItems collection, we must either manually add it to a DBSet on the context or inform the change tracker that the state for that line item was Added.
This means my domain objects must have an explicit dependency on Entity Framework and I must now somehow pass around references to the context (or change tracker) when calling business functions.
Is this something I should simply work around for the moment, on the basis that EF7 will ultimately have the same capabilities as EF6/NHibernate? Or is there a way to have rich domain objects without this dependency?
This can be solved by using dependency injection. This would allow separation of your domain objects from your ORM of choice (plus all the other benefits of dependency injection). There is no single, absolutely correct answer for how exactly you separate concerns in your code.
Related note: the behavior of .Add() will be changing in EF7 - beta 8 (See PR#2979). The change tracker will now include all "children" entities when you call .Add for a parent item.
Hi have a domain model which is nice and clean. Such as:
public class Blog
{
public int Id {get;set;}
public string Title {get;set;}
public string Body {gets;set;}
}
Why does Entity Framework force me to pollute the domain model with the RowVersion property to provide for concurrency?
My model doesn't want or need to know about this so why should I be forced to use it? Is there another way to perform concurrency checking? If so is it better/worse or faster/slower than adding a row version? Or can I add RowVersion somewhere else where it's not in the domain model. I'm using EF 4.1 with the fluent api.
Thanks
Try to use a base class and put all properties for security, concurrency checking in there.
I have several concerns when trying to do DDD development with EF 4.2 (or EF 4.1) code first. I've done some extensive research but haven't come up with concrete answers for my specific concerns. Here are my concerns:
The domain cannot know about the persistence layer, or in other words the domain is completely separate from EF. However, to persist data to the database each entity must be attached to or added to the EF context. I know you are supposed to use factories to create instances of the aggregate roots so the factory could potentially register the created entity with the EF context. This appears to violate DDD rules since the factory is part of the domain and not part of the persistence layer. How should I go about creating and registering entities so that they correctly persist to the database when needed to?
Should an aggregate entity be the one to create it's child entities? What I mean is, if I have an Organization and that Organization has a collection of Employee entities, should Organization have a method such as CreateEmployee or AddEmployee? If not where does creating an Employee entity come in keeping in mind that the Organization aggregate root 'owns' every Employee entity.
When working with EF code first, the IDs (in the form of identity columns in the database) of each entity are automatically handled and should generally never be changed by user code. Since DDD states that the domain is separate from persistence ignorance it seems like exposing the IDs is an odd thing to do in the domain because this implies that the domain should handle assigning unique IDs to newly created entities. Should I be concerned about exposing the ID properties of entities?
I realize these are kind of open ended design questions, but I am trying to do my best to stick to DDD design patterns while using EF as my persistence layer.
Thanks in advance!
On 1: I'm not all that familiar with EF but using the code-first/convention based mapping approach, I'd assume it's not too hard to map POCOs with getters and setters (even keeping that "DbContext with DbSet properties" class in another project shouldn't be that hard). I would not consider the POCOs to be the Aggregate Root. Rather they represent "the state inside an aggregate you want to persist". An example below:
// This is what gets persisted
public class TrainStationState {
public Guid Id { get; set; }
public string FullName { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
// ... more state here
}
// This is what you work with
public class TrainStation : IExpose<TrainStationState> {
TrainStationState _state;
public TrainStation(TrainStationState state) {
_state = state;
//You can also copy into member variables
//the state that's required to make this
//object work (think memento pattern).
//Alternatively you could have a parameter-less
//constructor and an explicit method
//to restore/install state.
}
TrainStationState IExpose.GetState() {
return _state;
//Again, nothing stopping you from
//assembling this "state object"
//manually.
}
public void IncludeInRoute(TrainRoute route) {
route.AddStation(_state.Id, _state.Latitude, _state.Longitude);
}
}
Now, with regard to aggregate life-cycle, there are two main scenario's:
Creating a new aggregate: You could use a factory, factory method, builder, constructor, ... whatever fits your needs. When you need to persist the aggregate, query for its state and persist it (typically this code doesn't reside inside your domain and is pretty generic).
Retrieving an existing aggregate: You could use a repository, a dao, ... whatever fits your needs. It's important to understand that what you are retrieving from persistent storage is a state POCO, which you need to inject into a pristine aggregate (or use it to populate it's private members). This all happens behind the repository/DAO facade. Don't muddle your call-sites with this generic behavior.
On 2: Several things come to mind. Here's a list:
Aggregate Roots are consistency boundaries. What consistency requirements do you see between an Organization and an Employee?
Organization COULD act as a factory of Employee, without mutating the state of Organization.
"Ownership" is not what aggregates are about.
Aggregate Roots generally have methods that create entities within the aggregate. This makes sense because the roots are responsible for enforcing consistency within the aggregate.
On 3: Assign identifiers from the outside, get over it, move on. That does not imply exposing them, though (only in the state POCO).
The main problem with EF-DDD compatibility seems to be how to persist private properties. The solution proposed by Yves seems to be a workaround for the lack of EF power in some cases. For example, you can't really do DDD with Fluent API which requires the state properties to be public.
I've found only mapping with .edmx files allows you to leave Domain Entities pure. It doesn't enforce you to make things publc or add any EF-dependent attributes.
Entities should always be created by some aggregate root. See a great post of Udi Dahan: http://www.udidahan.com/2009/06/29/dont-create-aggregate-roots/
Always loading some aggregate and creating entities from there also solves a problem of attaching an entity to EF context. You don't need to attach anything manually in that case. It will get attached automatically because aggregate loaded from the repository is already attached and has a reference to a new entity. While repository interface belongs to the domain, repository implementation belongs to the infrastructure and is aware of EF, contexts, attaching etc.
I tend to treat autogenerated IDs as an implementation detail of the persistent store, that has to be considered by the domain entity but shouldn't be exposed. So I have a private ID property that is mapped to autogenerated column and some another, public ID which is meaningful for the Domain, like Identity Card ID or Passport Number for a Person class. If there is no such meaningful data then I use Guid type which has a great feature of creating (almost) unique identifiers without a need for database calls.
So in this pattern I use those Guid/MeaningfulID to load aggregates from a repository while autogenerated IDs are used internally by database to make a bit faster joins (Guid is not good for that).
No issues really, this is more for my personal comprehension. Using MVC3 + EF 4.1 Code First. I'm trying to make a one-to-one relationship between a Provision and an Enactment.
I tried using the conventional way of making DbSet<Provision> and a DbSet<Enactment>. However, it turned out EF didn't like that. I had to change the OnModelCreation override to define the principal/dependent relationship (fyi Provision is principal, Enactment dependent). I had a bunch of errors and exceptions for some reason. So I tried something a tad creative:
I commented out the public DbSet<Enactment> Enactments { get; set; } line from my Context. Nonetheless, my Provision class still calls for a public virtual Enactment Enactment { get; set; } property. I thought that would make it so that a Provision will just save in its Enactment property an object of the Enactment class itself (if this sounds odd, I apologize I took up programming only a month ago and still learning). That was acceptable, since I thought I would be able to access the Enactment by looking at Provision.Enactment.<EnactmentProperty>.
What surprised me was that even with DbSet commented, the db still created an Enactments table mapped to my Enactment class properties. So if anything it seemed like I got an even better result than anticipated - but I just don't understand the logic behind my code now. Is commenting the particular DbSet and still getting a table normal in the circumstance? Am I playing with fire and should back away from this method?
Commenting DbSet doesn't matter. EF code first uses some conventions which will check you entities and mapping and infer all classes which should be mapped. So if you have any fluent mapping describing some entity or if any entity you explicitly mention in DbSet or mapping has navigation property to other class (which can be entity = EF is able to infer its primary key) it will be mapped as well.
After some NullReferenceException headache from deep down System.Data.Services I found out that data services doesn't like properties in the EF model marked as protected.
The exception occurs when the data service is initializing and tries to generate metadata for the EF model. Apparently Microsoft decided to throw a NullReferenceException when reflecting protected properties here rather than a meaningful message.
I use a few protected properties to wrap custom types not available in the database. This is a convenient way of representing for example enums in the database. The enum can be represented as a protected string property with a public enum wrapper that converts to and from the string value. This works very well in all other EF usage scenarios and I would rather not abandon the protected properties pattern.
I use self tracking entities that flows around nicely with WCF. Protected properties works well since I have checked "Reuse types in referenced assemblies", which makes my wrapper properties available in all assemblies. I was hoping that I could do something similar with a data service. I realize that I might run into trouble if I want to construct a query where the protected properties is part of the expression, but that is a different problem that could be addressed otherwise.
Is there a (practical) way to use protected entity properties with a data service?
If not, how should I best represent non-db types if I don't want to keep my set of public properties nice and clean?
Obviously I could just make everything public, but that would be a practice that rhymes with globals.
What about calling SetEntitySetAccessRule?