Hi,

We've got an entity called PostalCode. This Entity is pre-loaded at the start of the application. Here's the code:

public  partial class PostalCode : AbstractEntity , IComparable
    { // START partial class
        #region DataObjectsFields

        [Field(Nullable = true), FieldMapping("Code")]
        public string Z_Code { get;  set; }

        [Field(Nullable = true), FieldMapping("City")]
        public string Z_City { get;  set; }

        [Field(Nullable = true), FieldMapping("State")]
        public string Z_State { get;  set; }

        [Field(Nullable = false), FieldMapping("ManualEntry")]
        public bool Z_ManualEntry { get;  set; }

        [Field(Nullable = true), FieldMapping("PostReference")]
        public int? Z_PostReference { get;  set; }

        [Field(LazyLoad = true)]
        [Association(OnOwnerRemove = OnRemoveAction.Clear, OnTargetRemove = OnRemoveAction.Clear, PairTo = "Z_PostalCode")]
        public EntitySet<Address> Z_AddressList { get;  set; }

        [Field(Nullable = false), FieldMapping("CountryId")]
        [Association(OnOwnerRemove = OnRemoveAction.Clear, OnTargetRemove = OnRemoveAction.Clear)]
        public Country Z_Country { get;  set; }
        #endregion //END region DataObjectsFields
    }

The Entity is prefetched like so (don't get confused about the AllPostalCodeList, we just use lazy loading there):

PostalCodeListPreloaded = Query.ExecuteFuture<PostalCode>(() =>  from postalCode in Query.All<PostalCode>()
                                                                                    select postalCode);

        public static IEnumerable<PostalCode> PostalCodeListPreloaded {get; set;}

        int PostalCodeCount = PostalCode.AllPostalCodeList.Count;

        ...

        private static ObservableEntityList<PostalCode> m_AllPostalCodeList;

        /// <summary>
        /// The current list of all PostalCode items from DB. It is never 'null'
        /// </summary>
        public static ObservableEntityList<PostalCode> AllPostalCodeList
        { // START ClassList property       
            get
            { // START get ClassList
                if (m_AllPostalCodeList == null)
                {
                    if (ApplicationHelper.IsRunning)
                    {
                        m_AllPostalCodeList = new ObservableEntityList<PostalCode>("AllPostalCodeList", PreloadStrategy.PostalCodeListPreloaded.AsQueryable());
                    }
                    else // in design mode
                    {
                        m_AllPostalCodeList = new ObservableEntityList<PostalCode>("AllPostalCodeList");
                    }
                }
                return m_AllPostalCodeList;
            } // END get ClassList
        } // END ClassList property

The idea was to load the PostalCode Entities just once during startup, but the Prefetcher somehow disaggrees with us and reloads all PostalCode Entities during ApplyChanges() on the DisconnectedState.

Regards


Updated at 22.08.2010 11:58:38

I've debugged the DO code a bit (for as far as the code matched with our installed version) and see that somewhere in the routine below in the Session.cs the PostalCodes are all fetched:

public VersionSet CreateVersionSet(IEnumerable<Key> keys)
    {
      using (Activate())
      using (var tx = Transaction.Open()) {
        var entities = keys.Prefetch();
        var result = new VersionSet();
        foreach (var entity in entities)
          if (entity!=null)
            result.Add(entity, false);
        tx.Complete();
        return result;
      }
    }

Regards

This thread was imported from our support forum. The original discussion may contain more detailed answer.

asked Aug 22 '10 at 11:52

Paul%20Sinnema's gravatar image

Paul Sinnema
261878896

edited Sep 06 '10 at 04:54

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

Paul, see http://code.google.com/p/dataobjectsdotnet/issues/detail?id=784#c1 - now there is a delegate allowing you to refresh only a part of versions (you may use Key.Type to filter out some of them).

(Aug 27 '10 at 05:40) Alex Yakunin Alex%20Yakunin's gravatar image

One Answer:

This happens because:

  1. DisconnectedState.VersionsUsageOptions contains VersionsUsageOptions.Update flag (default value). This indicates that DisconnectedState must update content of its Versions (VersionSet) on fetches and ApplyChanges invocation.

  2. DisconnectedState.VersionsProviderType is set to VersionsProviderType.Session (default value). Indicates that new versions must be fetched from Session, to which changes are applied. This member is used only on ApplyChanges invocation.

  3. We use the code you provided to update versions after ApplyChanges. I.e. we always update versions of all cached entities.

We can provide e.g. DisconnectedState.VersionsFilter predicate indicating whether it's necessary to fetch (update) a version of specified entity, or not. Using it, you can filter out read-only entities.

Alternatively, I'm thinking about caching-related properties for [HierarchyRoot]. We're going to start development of this part soon (level 2 cache), so cache control directives are anyway necessary. And in this case we could use them automatically (i.e. all rarely changing entities require no version updates).

answered Aug 24 '10 at 10:59

Alex%20Yakunin's gravatar image

Alex Yakunin
29714412

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