I am trying to set up multiple DbContext objects in my solution. One will be the initialization context and the others will be bounded contexts.
The scenario I am having difficulty resolving is as follows:
Having two database tables, a parent object and a child object. Upon initialization the tables are created okay with all the properties on, however in the bounded context I want to use the parent object and only return a subset of properties from the child object.
At the moment both the initialization context and the bounded context use the same parent class so therefore I can't use a third info object for the child object in the bounded context.
Would I therefore need to create another parent object for use in the bounded context which uses another child object with subset of properties?
So would I need in the initialization context a parent and child object and in the bounded context a separate parent and child object where the child object only has a subset of properties and the parent object points to that child?
I am quite happy to create the child class with a subset of properties but it seems a bit long winded to create a separate parent object to point to the child info object but I can't see a way around this.
Having watched Julie Lermans TechEd Europe 2014 "Entity Framework Model Partitioning in Domain-Driven Design Bounded Contexts" https://www.youtube.com/watch?v=rGA_FNew-6g I have decided to go down the route of having a master context purely for database migrations.
I found the idea of using events and message queues and separating the data into different tables in the database interesting but it's probably a bit heavy handed for our needs at the moment.
Related
I'm using Prism framework with EF in WPF application.
ViewModel:
keeps service references (passed by unity container).
Services:
are providing "high level" operations with data
keeps reference of Repository, which provides basic CRUD operations with database (single table per repository).
Repository:
every method in repository uses the "using" pattern, where I work with short lived object context.
This is where i got stuck: after object context is disposed, I can not work with mapped properties no longer. My database model is complex (many related tables) and many .Include() calls when retrieving data keeps code dirty.
After reading several threads, I discovered that "unit of work" pattern is probably what I need.
Here comes my question:
Who keeps reference of unit of work (and therefore context)?
If I choose context per view approach, viewModel should have context reference.
How can I inject unit of work to my services then? Or should I create new instance of Service in ViewModel and pass context in constructor parameter?
We're using a similar architecture in a project:
Each ViewModel gets its own Service object which gets injected in the constructor (at least the top level ones that directly correspond to a View. Some hierarchical ViewModels may reuse their parent's Service, but let's keep it simple here).
By default, each Service operation creates a new context, but...
Services have BeginContext and EndContext methods which can be called
by the ViewModels to keep the context open over multiple operations.
This worked pretty well for us. Most of the time we call BeginContext when a View is opened and EndContext when it is closed.
FRom MSDN:
The EntityCollection<>.Attach method is used to define a relationship
between an object and a related object when both objects are already
exist in the object context
Since with non-POCO entities relationships are automatically handled by Object Services, are EntityCollection<>.Attach ( EntityReference<>.Attach ) only relevant with POCOs or are there also situations where they are useful even when using non-POCO entities?
thank you
Attach function is also used to link entities to the context when they have been created outside the context.
I am relatively new to entity framework, all the documents or books I can find are talking about how to use the framework, or which model should be used, but short of explanation how the framework works in depth.
For instance, when I load the entities from the database via either LINQ query or framework methods, are those entities thread safe? In another words can they be shared with other threads? If so how EF controls the consistency?
When control goes out of context, are those entities gone or still in memory? After .SaveChanges are those entities gone? What is the life cycle?
Can an expert in EF explain the above points in details please.
Thanks in advance.
The life cycle of loaded entities is more-or-less tied to that of the Entity Context which loaded them. Hence in many examples you will see:
using (var ctx = new Context())
{
// ... do work
} // The context gets disposed here.
Once the context is disposed (at the end of the using statement, e.g.), you should no longer treat entities that were loaded inside the context as if you can load additional information from them. For example, don't try accessing navigation properties on them. To avoid problems, I usually find it best to create a DTO that has only the exact data that I expect people to be able to use, and have that be the only value that leaves the using statement.
using (var ctx = new Context())
{
var q = from p in ctx.People
select new PersonSummary{Name = p.Name, Email = p.Email};
return q.ToList(); // This will fully evaluate the query,
// leaving you with plain PersonSummary objects.
}
Entity Contexts are not thread-safe, so you shouldn't be trying to load navigation properties and such from multiple threads for objects tied to the same context, even within the context's lifecycle.
For instance, when I load the entities from the database via either LINQ query or framework methods, are those entities thread safe? In
another words can they be shared with other threads? If so how EF
controls the consistency?
The ObjectContext class is not tread safe. You must have one object context per thread or to create you own thread synchronization process. This way the consistency is managed by the ObjectContext since it tracks all the objects' state.
When control goes out of context, are those entities gone or still in memory? After .SaveChanges are those entities gone? What is the life
cycle?
ObjectContext class inherit from IDisposable interface so you can, and should, use USING statement when using Entity Framework. This way they're gone after you close the using statement. If you DO NOT dispose the context they keep being tracked, only their states are changed. Disposing ObjectContext instances will also make sure that the database connection is properly disposed and you are not leaking database connections.
So, the big question is:
Where and when should EF live?
Theses ORM should be treated as the Unit of Work pattern, that is, the ORM object should live until the business task is done.
In my specific scenarios I use an IoC container like Windsor that does the heavy lifting for me. In an ASP.NET MVC app for example, Windsor can create a Context per Web Request. With this you don't have to write a lot of using statements throughout your code. You can read more about it here:
Windsor Tutorial - Part Seven - Lifestyles
Here's a link that explains it in more details directly from the guy that helps build the framework at Microsoft:
Entity Framework Object Context Life Cycle compared to Linq to Sql Data Context Life Cycle
You can write a test application to observe the behavior of the context tracker.
If you retrieve an entity from a context, then dispose of that context, then create a new instance of the context and attempt to save a change to the entity you retrieved earlier, it will complain that it is already tracking an entity with that ID.
When I use Entity Framework, I want to query out a record in a context and add it to another context with the same schema, after query out the record, I detach it from the context, but the related entities are all away, is there any way to solve it?
Thanks in advance!
This is "by design". EF can detach entities only one by one but in the same time EF doesn't support object graphs composed of attached and detached entities. Because of that when you detach entity it will break all relations to the rest of attached object graph. Detaching whole object graph is currently not supported but you can vote for this feature on Data UserVoice.
As a workaround you can turn off lazy loading on your context, use eager loading described by #CodeWarrior to load exactly data you need to pass to other context. Once you have data loaded serialize them to stream and immediately deserialize them to the new instance of the object graph. This is the way how to make deep clone of entity graph which is detached but has all relations intact (turning lazy loading off is needed otherwise serialization will load all other navigation properties as well which can result in much bigger object graph then expected). The only requirement is that your entities must be serializable by serializer of your choice (be aware of circular references which usually require some special handling or additional attributes on your entities).
Are you asking how to load the child entities? If so, you can do eager loading with the .Include method. Given a Person class and a PhoneNumber class where Person has a collection of PhoneNumber, you could do the following:
List<Person> People = db.People.Where(p => p.Name = "Henry")
.Include("PhoneNumbers")
.ToList();
Or you can do what is called explicit loading where you load your entities and call the .Load method on the collections of child and related entities that you want to load. Generally you do this when you do not have LazyLoading enabled (and LazyLoading is enabled by default in 4.0+ don't recall in previous versions).
Regardless of how you query and load them, you will have to detach entities that you want to attach to a different context.
Here is a link to a pretty good MSDN article on loading entities.
So I'm new to the concept of routed events, but I know that messages are flying everywhere when fields are changing via the RaiseDataMemberChanging / RaiseDataMemberChanged messages.
The quick question is how to I "listen" for those routed messages?
I would like my view model, in a MVVM correct matter, intercept a message that a field is being updated, deep down in the heirarchy of tables. If a change occurs in a child (a date range), that date range change has some business logic associated with it that works from top down.
I've know that I can use partial methods to inject code during the changing and changed events, but the design (one to one relationship) means that a change to the child, in the context of the child, has no reference the parent (Parent has a one to one reference to child, but child has no reference to parent).
Yes I can add the reference from the child to the parent (making the parent have both a one to one, as well as a one to many relationship), but during creation of the entity, this creates a problem - parent has to exist before the child entity exists, and the child entity has to exist before a reference to the parent can exist. This design requires an insert of the parent, and child, then an update of the child - which confuses WCF RIA Services during the inital creation process.
Sorry for the long winded explaination, but I'll even consider design changes if this all makes sense to anyone that cares to comment.
Any input would be appreciated.
I'm using a subscription to the PropertyChanged events of the Entity in question. It seems like a lot of work to filter out all the events for a couple of fields.
Using RX, I'm hoping that the resources used are minimal, and the weak reference avoids the memory link issue when a strong reference is used to deal with events:
Observable.FromEventPattern<PropertyChangedEventArgs>(this.FlowEntity, "PropertyChanged")
.Where(pPropertyChanged => (
pPropertyChanged.EventArgs.PropertyName.EndsWith("Date")) ||
pPropertyChanged.EventArgs.PropertyName == "Capacity"
)
.Subscribe(pObserver => this.RaiseFlowEntityDateChanged(this, pObserver.EventArgs));
FlowEntity is the child entity that I'm monitoring from the parent. I then raise custom event using the parent entity, rather than the entity that actually holds the event.
I can't raise this event from the partial methods, as the child entity would not have the context of the parent.