What does it do exactly? When should it be used?

asked Nov 25 '10 at 05:59

ara's gravatar image

ara
395858791


One Answer:

It loads bunch of DataObject instances into Session cache. Consequently all these objects become available without database roundtrip.

For example you have an array of Keys and you are going to iterate this array and to process some way corresponding DataObject instances. In this case Preload can help you to proceed this operation faster. It would look like the following:

// Large array of keys
Key[] allKeys = callContext.GetAllKeys();
int processedCount = 0;
int totalCount = allKeys.Length;
// Lets process all keys part by part
while (processedCount < totalCount) {
  int remainder = totalCount - processedCount;
  Key[] keys = new Key[remainder > maxPreloadCount ? maxPreloadCount : remainder];
  Array.Copy(allKeys, processedCount, keys, 0, keys.Length);
  processedCount += keys.Length;
  StrongReferenceHolder srHolder = session.Preload(keys); // Keep reference to srHolder to prevent garbage collection!!!
  // Now all objects from keys array are loaded into Session cache
  for (int index = 0, count = keys.Length; index < count; index++) {
    Key key = keys[index];
    NET.DataObject dObj = session[key]; // Will work without database roundtrip
    // All manipulations with dObj here
  }
  // Release preloaded instances references (Could be omited)
  srHolder.Clear();
}

(Example has taken from ObjectSetRequestProcessor the service which prepares offline instances to be sent to a client ObjectSet)

answered Nov 25 '10 at 13:22

Alex%20Ustinov's gravatar image

Alex Ustinov
2484

Great answer, Alex. What about QueryResult.Preload()?

What's the difference between iterating through entities in a QueryResult with and without a Preload() call?

Because in my tests with SQL Profiler running, I don't see a difference in database calls with and without Preload().

(Nov 25 '10 at 13:45) ara ara's gravatar image

Actually it does exactly the same because it internally calls Session.Preload(Key[] keys).

But additionally it is important to execute all operations within a single transaction, because otherwise DataObjects performs version check for every DataObject instance accessed.

(Nov 26 '10 at 00:38) Alex Ustinov Alex%20Ustinov's gravatar image
1

I had a query "select Customer instances" and iterated through each entity and printed their Name and PhoneNumber properties within a single transaction (including the query).

However, there was no difference in DB hits whether or not I used QueryResult.Preload().

So, how exactly does Preload() help with performance?

It seems that the query already retrieves and loads the returned entities, even if you don't call Preload.

(Nov 26 '10 at 04:48) ara ara's gravatar image

Good question. Yes, by default Query.Execute() method populates session and global caches with special InstantiationInfo instances. These instances hold DataObject' key, version and serialized FastLoadData. They also contain info about transaction this data were fetched. So, in the default case subsequent Preload call in the same transaction is definitelly useless. But it again will be useful in the case you accessing these data in a separate transaction.

(Nov 26 '10 at 05:57) Alex Ustinov Alex%20Ustinov's gravatar image

Now it's clear! Thank you!

(Nov 26 '10 at 05:58) ara ara's gravatar image

You can change the default Query behavior via QueryOptions. Please pay attention to 'LoadOnDemand' option. If it applied no FastLoadData will be extracted during Query execution, only Keys. The advantage of this option is that there will be no join with doDataObject table so the query will be faster. But in this case you always need to call Preload before iterate QueryResult

(Nov 26 '10 at 06:01) Alex Ustinov Alex%20Ustinov's gravatar image
Your answer
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!
toggle preview

powered by OSQA