Geeks With Blogs

News

Currently Reading

CLR via C#m
Under The Influence(of code) Abhijeet Patel's blog
Let's say we neede to process a bunch of entities coming from an XML file, create EDM entites for each XML element and eventually persist them. Very trivial to accomplish using a little bit of LINQ.

  1. <Roles>  
  2.   <Role name="Admin"/>  
  3.   <Role name="Reader"/>  
  4.   <Role name="Writer"/>    
  5. </Roles>  

  1. var doc = XDocument.Load("Roles.xml");  
  2. var roles = doc.Element("Roles").Elements("Role").Select(x => new Role { RoleName = (string)x.Attribute("name") });  
  3. PermissionsAPIContext context = new PermissionsAPIContext();  
  4.   
  5. foreach (var role in roles)  
  6. {  
  7.   context.AddToRoleSet(role);  
  8. }  
  9. context.Savechanges()  
But wait, let's make this a little interesting...

  1. <Roles>  
  2.   <Role name="Admin"/>  
  3.   <Role name="Reader"/>  
  4.   <Role name="Writer"/>  
  5.   <Role name="Reader"/>  
  6. </Roles>  
See the problem now? If we process the above XML using the code from before, we end up adding the same entity twice!
So what do we do now?
ObjectStateManager to the rescue, let's rewrite the piece of code as follows:

  1. var doc = XDocument.Load("Roles.xml");  
  2. var roles = doc.Element("Roles").Elements("Role").Select(x => (string)x.Attribute("name"));  
  3. PermissionsAPIContext context = new PermissionsAPIContext();  
  4. foreach (var role in roles)  
  5. {  
  6.    Role roleEntity = GetRole(role, context);  
  7.    if (roleEntity.EntityState == EntityState.Added || roleEntity.EntityState == EntityState.Detached)  
  8.    {  
  9.       context.AddToRoleSet(roleEntity);  
  10.    }                  
  11.  }  
  12. context.SaveChanges();  
  13.   
  14.   
  15. private static Role GetRole(string roleName,PermissionsAPIContext context)  
  16. {  
  17.   //NOTE: we could have used string.Compare(r.RoleName,roleName,true) == 0 inside the body of the lambda as a cleaner   
  18.   //way to do this but this translates to some pretty snarly and inefficient SQL!  
  19.     var roleEntity = context.RoleSet.FirstOrDefault(r => r.RoleName.Trim().ToLower() == roleName.Trim().ToLower());  
  20.     if (roleEntity == null)  
  21.      {  
  22.            var stateEntries = context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EtityState.Modified | EntityState.Unchanged);  
  23.            var roleEntityEntries = stateEntries.Select(s => s.Entity).OfType<Role>();  
  24.            roleEntity = roleEntityEntries.FirstOrDefault(r => r.RoleName.Trim().ToLower() == roleName.Trim().ToLower());  
  25.            if (roleEntity == null)  
  26.            {  
  27.                return new Role { RoleName = roleName };  
  28.            }  
  29.      }  
  30.      return roleEntity;  
  31. }  
A few of things note worthy here
1) In GetRoles() we first query the ObjectContext to check whether there is already a role present with the given name, if so we 
    simply return a reference to the existing entity instance
2) If the role is not existing then we check to see whether a role with the given name was added to the context, if so then we just
    get a handle to this previously added(but not yet persisted) role and return that.
3) If the role is not existing and was not added previously then we create a new Role entity and return.
4) The caller checks whether the returned entity is an existing one and if not it's added to the ObjectContext.

After we are done processing all entities, we save all entities and we are done.

The above mechanism allows us to safely sidestep duplicates while processing based on some equality rule(which in this case happens to be the role name).

Hope this helps.
Posted on Thursday, July 23, 2009 1:41 AM C# , Entity Framework | Back to top


Comments on this post: Retrieving Added Entities from the ObjectStateManager to avoid duplication

# re: Retrieving Added Entities from the ObjectStateManager to avoid duplication
Requesting Gravatar...
"Hope this helps. "

> answer: this helps! :) thx
Left by César on Aug 12, 2009 9:38 AM

# re: Retrieving Added Entities from the ObjectStateManager to avoid duplication
Requesting Gravatar...
So you are doing exactely the work a mature ORM is supposed to do, don't you?
Left by Post a Comment on Nov 08, 2010 4:13 PM

# re: Retrieving Added Entities from the ObjectStateManager to avoid duplication
Requesting Gravatar...
I like this information and it has given me some sort of desire to have success for some reason, so thanks. Furthermore I′m definitely considering blogging these facts in my own blog!
Left by UGG Bailey Button on Dec 17, 2010 8:14 PM

# re: Retrieving Added Entities from the ObjectStateManager to avoid duplication
Requesting Gravatar...
answer: this helps!
Left by cartier love bracelet on Mar 07, 2013 5:36 PM

Your comment:
 (will show your gravatar)


Copyright © Abhijeet Patel | Powered by: GeeksWithBlogs.net