This is a migrated thread and some comments may be shown as answers.

Lazy loading/change tracking with no reflection, stateful navigation

4 Answers 120 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
nagir
Top achievements
Rank 1
nagir asked on 27 May 2009, 01:38 AM
Hi,
Just wondering how is it possible to do lazy loading and change tracking without using reflection. How OA technically achieves this.

Another questions is if following tests will pass in OA:

public void AddingPostAssignsBlog() { 
  Blog b = new Blog(); 
  Post p1 = new Post(); 
  Post p2 = new Post(); 
 
  b.Posts.Add(p1); // Not this: b.AddPost(p1) 
  b.Posts.Add(p2); 
 
  Assert.AreSame(b, p1.Blog); 
  Assert.AreSame(b, p2.Blog); 
 
public void AddingBlogAssignsPost() { 
  Blog b = new Blog(); 
  Post p1 = new Post(); 
  Post p2 = new Post(); 
 
  p1.Blog = b; 
  p2.Blog = b; 
 
  Assert.AreEqual(2, b.Posts.Count); 
}  


Additionally how OA will behave in this scenario:
Blog b1 = new Blog(); 
Blog p2 = new Blog(); 
Post p = new Post(); 
p.Blog = b1; // p is in b1 
b2.Posts.Add(b); // b is in b2!!  






Thanks,
Dmitriy.

4 Answers, 1 is accepted

Sort by
0
nagir
Top achievements
Rank 1
answered on 28 May 2009, 06:33 AM
Anybody?
0
Zoran
Telerik team
answered on 29 May 2009, 07:42 AM
Hello Dmitriy,

OpenAccess uses the a code-injection mechanism called enhancement to inject code in assemblies containing persistent classes. You can see that if you open an enhanced assembly with the reflector. That cares about all functionality like lazy-loading change-tracking caching etc..

Regarding your second question, the first test would not pass the Assert because your persistent objects do not have any relationship to an object scope. Also you should have set the manage collection functionality of the Blog.Posts collection to true so that the scope can resolve the references. Here is a sample how the test would pass:
using (IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope()) 
   scope.Transaction.Begin(); 
   Blog b = new Blog(); 
   scope.Add(b); 
   Post p1 = new Post(); 
   Post p2 = new Post(); 
   b.Posts.Add(p1); //The references are resolved by the object scope here and  
   b.Posts.Add(p2); //here in case you have a managed collection 
   Assert.AreSame(b, p1.Blog);  
   Assert.AreSame(b, p2.Blog);  
   scope.Transaction.Commit(); //Here you can call Rollback as well 
 
 

The second test would not pass because the collection of the blog is not calculated before you push the Post objects on the server. Here is how the working code could look:
using (IObjectScope scope = ObjectScopeProvider1.GetNewObjectScope()) 
    scope.Transaction.Begin(); 
    Blog b = new Blog();  
    Post p1 = new Post();  
    Post p2 = new Post();  
 
    p1.Blog = b;  
    p2.Blog = b;  
    scope.Add(p1);     
    scope.Add(p2); 
    scope.Transaction.Commit(); 
 
    scope.Transaction.Begin();  
    Assert.AreEqual(2, b.Posts.Count); //Here because we are in a new transaction the collction of "b" is recalculated 
    scope.Transaction.Rollback(); 

When you have a case like the third one - the behavior is the following: when you say p.Blog = b1  - p has reference to b1, but b1.Posts collection is not updated - that would happen after you commit a transaction and then access b1.
After you execute b2.Posts.Add(p) - p is added to the b2.Posts collection but it still has the reference p.Blog==b1;

If you add these objects in the database though, p will be associated with b2 - the blog whose collection was altered in case you have switched manage collection to true. If manage collection is turned off for the posts collection - p will be inserted with a reference to the b1 Blog.

I hope this makes work with OpenAccess more clear for you.

Best wishes,
Zoran
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
nagir
Top achievements
Rank 1
answered on 29 May 2009, 09:18 AM
Hi Zoran,

Thanks a lot. It's not clear.

One more question. You say that OpenAccess uses the a code-injection mechanism called enhancement to inject code in assemblies containing persistent classes.

I have just had a look at the samples and do not see any post-build actions defined in projects (I see only ProjectExtensions/UserProperties in a .csproj file).
So how and at what stage the assembly gets injected?

Thanks,
Dmitriy.
0
Accepted
Zoran
Telerik team
answered on 29 May 2009, 02:57 PM
Hello Dmitriy,

When you enable a project to use OpenAccess the entries you have seen in the .csproj files are inserted. The project after that has some properties added one of which  is "Enhancing". If "Enhancing" is enabled, which is the default, the enhancer code is injected on compilation. You can not see the injected code in .csproj or other project files, but only in the already compiled assembly. Open the compiled assembly with .NET Reflector and you can see the code by the enhancer.


All the best,
Zoran
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
Tags
General Discussions
Asked by
nagir
Top achievements
Rank 1
Answers by
nagir
Top achievements
Rank 1
Zoran
Telerik team
Share this question
or