New Posts New Posts RSS Feed: Problem with Include
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Problem with Include

 Post Reply Post Reply
Author
huy View Drop Down
Newbie
Newbie


Joined: 16-Jan-2012
Posts: 3
Post Options Post Options   Quote huy Quote  Post ReplyReply Direct Link To This Post Topic: Problem with Include
    Posted: 16-Jan-2012 at 1:46am
Hi,

Say I'd like to do a query like this:
_manager.Customers.Where(c => c.Id == 10).Include("Orders").With(QueryStrategy.DataSourceThenCache);

The first time it run well, I should have a customer id = 10 and 5 Orders, for instance.
Then I delete an Order using SQL Server Management Studio and run the query again.

I still got 5 Orders instead of 4. I think it is related to entity cache but I don't know how to handle it properly.

Could you please help me ?
Back to Top
DenisK View Drop Down
IdeaBlade
IdeaBlade


Joined: 25-Aug-2010
Posts: 715
Post Options Post Options   Quote DenisK Quote  Post ReplyReply Direct Link To This Post Posted: 18-Jan-2012 at 11:24am
Hi huy,

This is the correct behavior because when you delete an order using the Management Studio, you're not using DevForce to mark the order deleted so the second query actually retrieves 4 but since the deleted order is still in the cache, you're seeing 5.

To handle this properly, you can refresh your EntityManager's cache by clearing it ( EntityManager.Clear () ) and then re-query.

Please note that when you build your application, you probably don't want your users to delete any record using the Management Studio.

Please see this page, http://drc.ideablade.com/xwiki/bin/view/Documentation/create-modify-delete, to help you understand how to do CUD (Create, Update/Modify, Delete) operations using DevForce.

Hope this helps.
Back to Top
huy View Drop Down
Newbie
Newbie


Joined: 16-Jan-2012
Posts: 3
Post Options Post Options   Quote huy Quote  Post ReplyReply Direct Link To This Post Posted: 18-Jan-2012 at 4:09pm
Hi DenisK,

Yes, I understand what you mean, no one will delete records at Management Studio level but this is very common in multi users environment. If a user uses your application to delete a record, you will have the same problem on your side.

Clearing the cache is ok but it is not what I expect. I want my application has such behavior.

When a user open a Customer detail screen, for instance, it will first check this Customer if it exists in cache.
If yes, it will show the screen with the cached version of this Customer and run a query with DataSource stragety to refresh data.
If No, it will get data from DataSource and then show to user.
If we have error from getting data from server, the user can still work with the cached version of the Customer.

Clearing the cache will disable this idea and will show empty data or raise error. Moreover, the application will not have "Offline" feature, the main reason that we choose to use DevForce.

Is there anyway to access related entities that are queried along with the root entity using "Include" to pre-process them before they are merged with the EntityManager's cache?
Back to Top
DenisK View Drop Down
IdeaBlade
IdeaBlade


Joined: 25-Aug-2010
Posts: 715
Post Options Post Options   Quote DenisK Quote  Post ReplyReply Direct Link To This Post Posted: 18-Jan-2012 at 4:57pm
Ah I see what you're asking now. Yes, there's a way to refresh your cache by calling EntityManager.RefetchEntities.

http://drc.ideablade.com/xwiki/bin/view/Documentation/forced-refetch-query 

Consider the following example below.

      //Create 1 EntityManager called mgr1. Prime it with 1 customer and 1 order
      var mgr1 = new NorthwindIBEntities();
      var newCust = CreateTestCustomer(mgr1);
      var newOrder = CreateTestOrder(mgr1);
      newCust.OrderSummaries.Add(newOrder);
      mgr1.SaveChanges();

      //Create another EntityManager called mgr2. Query the newly created customer
      var mgr2 = new NorthwindIBEntities();
      var newCust2 = mgr2.Customers.Where(c => c.Id == newCust.Id).Include(c => c.OrderSummaries).FirstOrNullEntity();
      var newOrder2 = newCust2.OrderSummaries.FirstOrDefault();

      //Delete the order
      newOrder2.EntityAspect.Delete();
      mgr2.SaveChanges();

      //Refresh mgr1 by calling RefetchEntities
      mgr1.RefetchEntities(newCust.OrderSummaries, MergeStrategy.OverwriteChanges);

      //Now verify that order has indeed been deleted
      Assert.IsTrue(newOrder.EntityAspect.EntityState.IsDetached());
      Assert.IsTrue(newCust2.OrderSummaries.Count == 0);


Edited by DenisK - 18-Jan-2012 at 4:58pm
Back to Top
huy View Drop Down
Newbie
Newbie


Joined: 16-Jan-2012
Posts: 3
Post Options Post Options   Quote huy Quote  Post ReplyReply Direct Link To This Post Posted: 18-Jan-2012 at 8:29pm
Hi DenisK,

Thanks for your suggestion but I'm affraid I can't implement it that way. Although refetch works perfectly but it only gets one entity type at a time. If your root entity has 5 relations, you will need to call refetch 5 times. I tried to refetch a batch of entities of different type in one call but it still makes differents calls for each type.

The requirement is minimizing the server side queries while maintaining the "up to date" version of data.

Finally, I was able to implement it to meet the requirement.

Thanks for your support.
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down