Up Query

Requery

Last modified on October 27, 2011 13:11

There are several ways of forcing the requery of previously cached data. This can important when you want to insure that the local entity cache has the absolutely latest data.  

One approach is to use one of the RefetchEntities overloads on the EntityManager:



RefetchEntity/RefetchEntities methods

C#
public void RefetchEntity(Object entity, MergeStrategy mergeStrategy);
public void RefetchEntities(IEnumerable entities, MergeStrategy mergeStrategy);
public void RefetchEntities(EntityKeyList entityKeys, MergeStrategy mergeStrategy);
public void RefetchEntities(EntityState entityState, MergeStrategy mergeStrategy);
VB
Public Sub RefetchEntity(ByVal entity As Object, ByVal mergeStrategy As MergeStrategy)
Public Sub RefetchEntities(ByVal entities As IEnumerable, ByVal mergeStrategy As MergeStrategy)
Public Sub RefetchEntities(ByVal entityKeys As EntityKeyList, ByVal mergeStrategy As MergeStrategy)
Public Sub RefetchEntities(ByVal entityState As EntityState, ByVal mergeStrategy As MergeStrategy)

There are also asynchronous versions of each of the above.

One warning about these methods; they are all designed to work with reasonably small numbers of entities ( < 1000). 

While they will work with larger numbers of entities; performance may be poor.  The reason for this is that these methods are implemented so that they in effect create a large "IN" or "OR" query for all of the desired entities by key.  The query expression itself can therefore become very large for large numbers of entities.  

Expressions that are this large will have performance impacts in both serialization as well as query compilation.  For those cases where very large numbers of entities need to be refreshed, it is usually a better idea to write a "covering" query that is much smaller textually but returns approximately the same results.  You may find that even though you return more entities than are needed with this covering query, the resulting overall performance is still better.

The MergeStrategy determines how the refetched data will be merged into cache. OverwriteChanges replaces the cached entities, overwriting our pending changes. We often want to (a) keep pending changes but (b) refresh copies of unmodified entities. The PreserveChanges… strategies can help us achieve our purpose.

StrategyDescription
OverwriteChangesOverwrites the cached entity with incoming data and uses the EntityState of the incoming entity
PreserveChangesReplace unchanged entities but keep changed entities as they are.
PreserveChangesUnlessOriginalObsoletePreserves the persistent state of the cached entity if the entity is current. Overwrites an entity if it is obsolete and gives it the EntityState of the incoming entity.
PreserveChangesUpdateOriginalPreserves the persistent state of the cached entity whether it is current or not. Overwrites the Original version of the entity if obsolete.

How is Current determined? DevForce uses the ConcurrencyProperties you’ve defined for the Entity. If the values of the concurrency properties are the same between the original and incoming entity, then the entity is considered current. If you haven’t defined a concurrency property for the entity then DevForce has no way of determining currency correctly, so assumes that the entity is current.

What do we mean by the Original version? Every entity can have up to three “versions” of property values. All entities will have “current” values; modified entities will also have “original” values, i.e., the property values before the entity was modified. Entities in edit mode will also have “proposed” values, i.e., the values changed during the edit but not yet committed.

Merge strategies are described in further detail later in this document.

 

Fetch and Re-fetch of navigation properties

You can also control how navigation properties are loaded, or force a re-load, using property metadata for these properties called the NavigationEntityProperty. Remember that every generated entity in the domain model has a nested PropertyMetadata class giving you access to all EntityProperty definitions for that type. You can also obtain this information from the EntityMetadataStore.

With the NavigationEntityProperty for a particular property in hand, you can then obtain the EntityReference, which gives you low-level access to the property and its status. You obtain the EntityReference from the NavigationProperty itself. For example,

C#
Customer aCustomer = _em1.Customers.First();
var navProp = Customer.PropertyMetadata.OrderSummaries;
var entityRef = navProp.GetEntityReference(aCustomer);
VB
Dim aCustomer As Customer = _em1.Customers.First()
Dim navProp = Customer.PropertyMetadata.OrderSummaries
Dim entityRef = navProp.GetEntityReference(aCustomer)

Once you have the EntityReference, a call to Load(MergeStrategy) will force a re-fetch of the related entities, and use the specified MergeStrategy to merge the data into cache. The MergeStrategy here functions exactly the same as when used with the EntityManager RefetchEntities methods described above.

C#
Customer aCustomer = _em1.Customers.First();
Customer.PropertyMetadata.OrderSummaries.GetEntityReference(
  aCustomer).Load(MergeStrategy.PreserveChangesUpdateOriginal);
VB
Dim aCustomer As Customer = _em1.Customers.First()
Customer.PropertyMetadata.OrderSummaries.GetEntityReference(aCustomer) _
  .Load(MergeStrategy.PreserveChangesUpdateOriginal)

By default, all navigation properties are lazily loaded. To change this “load strategy” you can do so easily using the ReferenceStrategy defined for every NavigationEntityProperty. For example,

C#
var ers = new EntityReferenceStrategy(
  EntityReferenceLoadStrategy.Load,
    MergeStrategy.PreserveChanges);
var navProp = Customer.PropertyMetadata.OrderSummaries;
navProp.ReferenceStrategy = ers;
VB
Dim ers = New EntityReferenceStrategy(EntityReferenceLoadStrategy.Load, _
  MergeStrategy.PreserveChanges)
Dim navProp = Customer.PropertyMetadata.OrderSummaries
navProp.ReferenceStrategy = ers

The EntityReferenceLoadStrategy is an enum which allows you to choose among "Lazy", "DoNotLoad", and "Load" options. The default, “Lazy” indicates that the related data will be loaded once when first accessed. Use "DoNotLoad" if the related data should not ever be retrieved from the back end data store; and use "Load" to force a retrieval from the back end data store upon every access.

Created by DevForce on October 04, 2010 16:06

This wiki is licensed under a Creative Commons 2.0 license. XWiki Enterprise 3.2 - Documentation. Copyright © 2012 IdeaBlade