Programming Guide > Working with Entities in Code |
Entity Framework DataSource (EF DataSource) is non-intrusive in the sense that you can do whatever you want with entities in code using the regular Entity Framework (or RIA) methods and properties and that will work well with EF DataSource. You can add, delete and modify entities using the regular methods (no special EF DataSource object model is needed for that), and EF DataSource collections will automatically reflect changes that you make to the entities. For example, to add a new entity, you don't need to use some special EF DataSource method; therefore, none exists. Just add a new entity as you always do in EF (or RIA) and it will automatically appear in corresponding EF DataSource collections. If an EF DataSource collection has a Where condition, it will appear there only if it satisfies the condition. Same with deleting and modifying entities: do it the regular EF (or RIA) way, and EF DataSource reflects the changes automatically, so they are automatically reflected in bound controls.
However, there is one important restriction that must be strictly observed. It does not limit what you can do; it only requires you in some (relatively rare) cases to add a method call to your code notifying EF DataSource of what you are doing:
CAUTION
Never fetch entities from the server by directly querying the context without notifying EF DataSource.
All entities must be either fetched by one of the EF DataSource's GetItems methods, or, if you want to fetch them by querying an object context directly, you must call the ClientScope.AddRef method to notify EF DataSource that you fetched entities from the server.
If you use the C1DataSource control or ClientViewSource, you fetch entities either implicitly if AutoLoad = true, or explicitly when you call the ClientViewSource.Load method. In both cases it is done through EF DataSource, so EF DataSource is aware of the newly fetched entities. When you need to fetch entities in code without using ClientViewSource, the standard way to do it is by using one of the EF DataSource's GetItems methods (EntityClientScope.GetItems|keyword=EntityClientScope.GetItems method, RiaClientScope.GetItems|keyword=RiaClientScope.GetItems method). Here too, EF DataSource is aware of the fetched entities. However, occasionally you may need to retrieve entities by issuing a query directly to the server without involving EF DataSource. For example, in Entity Framework you can take an ObjectContext that is used by EF DataSource and create queries:
C# |
Copy Code
|
---|---|
ObjectContext context = scope.ClientCache.ObjectContext; // or ObjectQuery query = ((NORTHWNDEntities)context).Customers; // or query = context.CreateObjectSet<Customer>(); // or query = context.CreateQuery<Customer>("..."); |
In RIA Services such code can look like this:
C# |
Copy Code
|
---|---|
DomainContext context = scope.ClientCache.DomainContext; var query = ((DomainService1)context).Customers; // or var entities = context.Load( ((DomainService1)context).GetCustomersQuery()).Entities; |
Having a query, you can get entities directly from the server by enumerating the query result:
C# |
Copy Code
|
---|---|
foreach (Customer c in query) /* do something */ |
or by binding a control to it:
C# |
Copy Code
|
---|---|
dataGrid.ItemsSource = query; |
If you do this without calling ClientScope.AddRef, you can get entities from the server without EF DataSource knowing about it. Those entities will be in the same cache with other entities, indistinguishable from them, so EF DataSource will manage them as other entities, including possibly releasing them, evicting them from the cache when it does not need them. That will make the entities inaccessible, but your program may still need them! So, very bad things can happen if you fetch entities to a EF DataSource-governed context without using EF DataSource and without notifying it that entities are fetched. Fortunately, adding that notification is easy, just call ClientScope.AddRef for all fetched entities like this:
C# |
Copy Code
|
---|---|
foreach (Customer c in query) { scope.AddRef(c); // do something } |
It will tell EF DataSource that the entities should not be released as long as the scope is alive.