I'm using POCO with EF4 and have problem deleting a child object from the parent. Consider the following scenario:
public class Order
{
public List<OrderItem> Items { get; private set; }
}
I need to delete an OrderItem from an Order object like:
myOrder.Items.Remove(0);
I expect EF to keep track the changes and delete the associated OrderItem when I call ObjectContext.SaveChanges().
However, I have realized this is not possible without calling Context.DeleteObject(). I believe this is not a true POCO way as my domain model shouldn't be aware of my persistence infrastructure.
Does anyone have a work around this issue?
Cheers,
Mosh
However, I have realized this is not
possible without calling
Context.DeleteObject(). I believe this
is not a true POCO way as my domain
model shouldn't be aware of my
persistence infrastructure.
I would not follow your interpretation. If you have in-memory collections of orders and order items (ignoring the persistence infrastructure), it's a difference if you only remove an item from the order's item collection or if you also delete the item from the in-memory repository. It might be possible that you want to remove the item only from one order, keep it existing and assign it to another order. (It wouldn't probably make much sense in case of orders and order items, but that's business logic and your POCOs and their relationships cannot know that you want to delete the item from the repository everytime you remove it from an order.)
So, you have to tell explicitely that the item should be deleted from the repository - for an in-memory repository and for a persistence related repository as well. You have to call DeleteObject for the item, there is no workaround to avoid this.
What referential integrity do you have setup in the DB? You have only asked for the orderitem to be removed from the item - not for it to be deleted, and that is what is happening.
Related
We have recently decided to use EF6 code first in one of our projects so I am undergoing a paradigm change. I really enjoy EF but some things are so different they seem wrong.
I just want to run a scenario by the community to see if I am thinking correctly.
We have an entity that has child entities of the same type.
If I was saving a child normally I would just save a new entity with the parent id set to the id of the parent. In the entity world they are connected through a navigation property of the same type as follows:
public class SomeType
{
public id;
....
public virtual IList<SomeType> Children
}
Obviously the standard approach doesn't work here since I am not manipulating DB foreign keys manually.
It seems the "Entity Way" would be to first use DBCcontext and linq to select the parent, then add the new entity to the Children list and save the whole thing.
Which is fine and logical - but it just seems a little inefficient to do a select every time i am doing a save.
Am I really missing something here do I just need to get used to a different way of thinking here?
Thank you!
If I'm getting your problem right, then you can and should save the child as a simple Sometype with a parentId, just as you would without using the entity framework. The automagic of the EF shouldn't cause a problem for you here, and you would not be breaking any best practices.
Essentially: If the parent entity is already loaded into context, it's usually best to add the new entity to the collection of navigation properties (Children in your case, but any foreign key). If the parent is not loaded and you know it's id, populate the foreign key field and save it just as you always did.
I would like to use one of the ideas that Jimmy Nilsson mentioned in his book Applying DDD with Patterns, and that is if i have an entity like a Product for example, i would like to take a snapshot of that entity for historic information, something like ProductSnapshot but i wonder how i might be able to implement this with an ORM (i am currently using Entity Framework). The main problem i am facing is that if i have another Entity like OrderLine that receives the Product via its constructor then entity framework would need you to make a public property of the type you wish to persist so this will force me to have something like this:
class OrderLine {
public Product Original Product {get; set;}
public ProductSnapshot Snapshot {get; set;}
}
and that seems awkward and not intuitive and i don't know how to deal with it properly when it comes to data binding (to which property i should bind), and finally i think that Product is an Entity while ProductSnapshot is a Value Object plus the snapshot is only taken when the OrderLine is accepted and after that the Product is not needed.
When doing DDD, forget that the database exists. This means the ORM doesn't exist either. Now, because you don't have to care about persistence and ORM limits, you can model the ProductSnapshot according to the domain needs.
Create a ProductSnapshot class with all the required members.This class would be a result probably of a SnapshotService.GetSnapshot(Product p) . Once you have the ProductSnapshot just send it to a repository SnapshotsRepository.Save(snapshot) . Being a snapshot, this means it will probably be more of a data structure, a 'dumb' object. It also should be invariable, 'frozen' .
The Repository will use EF to actually save the data. You decide what the EF entities and relations are. ProductSnapshot is a considered to be a business object by the persistence(it doesn't matter if in reality it's just a simple Dto) and the EF entities may look very different (for example, I store business objects in serialized form in a key-value table) according to your querying needs.
Once you define the EF entites you need to map the ProductSnapshot to them. It's very probable that ProductSnapshot itself can be used as an EF Entity so you don't need to do any mapping.
The point is, that taking a snapshot seems to be domain behavior. You deal with the EF only after you have the snapshot and you do exactly as you'd do with any other busines object.
Why does OrderLine have to have ProductSnapshot property? I suppose, you can either have a link to ProductSnapshot from Product class if you need to get that historical informatil, or, in case you just want to save Product state under some conditions, just implement a SaveSnapshot method in Product partial class, or have an extension method for it.
For a while now I have been wondering why when using JPA, do I have to write my delete methods like this:
#Transactional
public void delete(Account account)
{
if (entityManager.contains(account))
{
entityManager.remove(account);
}
else
{
entityManager.remove(entityManager.merge(account));
}
}
Perhaps the contains isn't needed since the transaction begins and ends with this method, but I still wonder why the remove couldn't just take an unmanaged object. Is it because it needs to be managed in order to know what the id is for that object? Any other insights would be great to hear. I just want to understand the hows and whys of the JPA remove.
The remove operation can be cascaded to associations of an entity.
To be able to know which associated entities to remove, the entity manager can't rely on a detached entity, since, by definition, this detached entity doesn't reflect the latest state of the entity, and doesn't necessarily have all its cascaded associations recursively loaded.
So, if it accepted a detached entity, remove() would have to decide for you: either merge the detached entity and execute the remove operation based on what the detached entity contains, or simply load the entity having the same ID as the detached entity, and execute the operation based on the loaded entity.
Instead of deciding for you, it simply requires an attached entity. That way, you decide what you want.
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).
I've just been talking with a colleague about Entity Framework change tracking. We eventually figured out that my context interface should have
IDBSet<MyPoco> MyThings { get; }
rather than
IQueryable<MyPoco> MyThings { get; }
and that my POCO should also have all it's properties as virtual.
Using the debugger we could then see the tracking objects and also that the results contained proxies to my actual POCOs.
If I don't have my POCO properties as virtual and have my context interface using IQueryable<> instead of IDbSet<> I don't get any of that.
In this instance I am only querying the database, but in the future will want to update the database via Entity Framework.
So, to make my life easier in the future when I come to look at this code as a reference, is there any performance penalty in having the tracking info/proxies there when I will never make use of them?
There is a performance penalty of tacking entities in EF. When you query using entity framework EF will keep a copy of values loaded from database. Also single Context instance keeps track of only single instance of an entity. So EF has to check whether it already has a copy of the entity before it creates an instance(ie. There will be lot of comparisons going behind the scenes).
So avoid it if you don't need it. You can do so as follows.
IQueryable<MyPoco> MyThings { get { return db.MyThings.AsNoTracking(); } }
MSDN page on Stages of Query Execution details the cost associated with each step of query execution.
Edit:
You should not expose IDBSet<MyPoco> MyThings because that tells the consumer of your API that your entities can be added, updated and deleted when in fact you intend to query the data.
Navigation properties in the model classes as declared as virtual so as to imply lazy load feature which means the navigation property will only be needed if required. As far as the Entity objects are concerned, there main aim is to load the specific table records from the database into the DbSet which comes from DbContext. You can't use IQueryable in this case. Also, it doesn't make any sense with the DataContext. IQueryable is an altogether different interface