Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Entity Framework - Object Services Level. Inserting and ObjectStateManager.

Blogs

Mike Taulty's Blog

Elsewhere

I'll try and exercise that ObjectStateManager a little by inserting some data (and keeping it all very simple by just playing with the Shippers table).

Starting with this;

    static void Main(string[] args)
    {
      using (NorthwindContext ctx = new NorthwindContext("Name=NorthwindEntities"))
      {
        ObjectQuery<Shippers> query = ctx.Shippers;

        DumpShippers(query);

        DumpObjectStateManager(ctx.ObjectStateManager);
      }
    }
    static void DumpShippers(IEnumerable<Shippers> shippers)
    {
      Console.WriteLine("Dumping");
      foreach (Shippers s in shippers)
      {
        Console.WriteLine("\tShipper id [{0}], name [{1}], tel [{2}]",
          s.ShipperID, s.CompanyName, s.Phone);
      }
    }

Note that the function DumpObjectStateManager was listed in a previous post and outputs this (I've snipped a little out as it gets a bit big - also, note that I've got 4 rows in my Shippers table);

Dumping Object State Manager
        Dumping objects in state [Detached]
        Dumping objects in state [Unchanged]
                Entity from entity set [Shippers], key [<Key=ShipperID,Value=1>]

                Entity from entity set [Shippers], key [<Key=ShipperID,Value=2>]

                Entity from entity set [Shippers], key [<Key=ShipperID,Value=3>]

                Entity from entity set [Shippers], key [<Key=ShipperID,Value=10>]
        Dumping objects in state [Added]
        Dumping objects in state [Deleted]
        Dumping objects in state [Modified]

So, we can see that the ObjectStateManager now knows about 4 entities from my Shippers entity set and it knows that I haven't changed them.

What if I do an insert and add a new Shippers entry?

 using (NorthwindContext ctx = new NorthwindContext("Name=NorthwindEntities"))
      {
        DumpShippers(ctx.Shippers);
        DumpObjectStateManager(ctx.ObjectStateManager);

        Shippers newShipper = new Shippers()
        {
          CompanyName = "New Company",
          Phone = "123 456 789"
        };
        ctx.AddObject("Shippers", newShipper);

        DumpShippers(ctx.Shippers);
        DumpObjectStateManager(ctx.ObjectStateManager);
      }

Now, you might naturally expect that when we DumpShippers() for the 2nd time, we would get our new entry in that list. We don't. However, that entry hasn't been lost and we can see that the ObjectStateManager is very well aware of it as in the output from the 2nd call to DumpObjectStateManager above;

Dumping Object State Manager
        Dumping objects in state [Detached]
        Dumping objects in state [Unchanged]
                Entity from entity set [Shippers], key [<Key=ShipperID,Value=1>]

                Entity from entity set [Shippers], key [<Key=ShipperID,Value=2>]

                Entity from entity set [Shippers], key [<Key=ShipperID,Value=3>]

                Entity from entity set [Shippers], key [<Key=ShipperID,Value=10>]
        Dumping objects in state [Added]
                Entity from entity set [Shippers], key [<Key=Temporary>]
        Dumping objects in state [Deleted]
        Dumping objects in state [Modified]

So, we can see that we have a Shippers entry in the Added state with a Temporary key and this is not being returned as part of the Shippers entity set because it's in "limbo" between the program and the store at this point.

If we make the change live in the store with something like;

      using (NorthwindContext ctx = new NorthwindContext("Name=NorthwindEntities"))
      {
        DumpShippers(ctx.Shippers);
        DumpObjectStateManager(ctx.ObjectStateManager);

        Shippers newShipper = new Shippers()
        {
          CompanyName = "New Company",
          Phone = "123 456 789"
        };
        ctx.AddObject("Shippers", newShipper);

        ctx.SaveChanges(true);

        DumpShippers(ctx.Shippers);
        DumpObjectStateManager(ctx.ObjectStateManager);
      }

Then the output from the final two "Dump" functions is;

Dumping
        Shipper id [1], name [Speedy Express], tel [(503) 555-9831]
        Shipper id [2], name [United Package], tel [(503) 555-3199]
        Shipper id [3], name [Federal Shipping], tel [(503) 555-9931]
        Shipper id [10], name [Mike Shipping Co], tel [123 456 789]
        Shipper id [11], name [New Company], tel [123 456 789]

Dumping Object State Manager
        Dumping objects in state [Detached]
        Dumping objects in state [Unchanged]
                Entity from entity set [Shippers], key [<Key=ShipperID,Value=1>]

                Entity from entity set [Shippers], key [<Key=ShipperID,Value=2>]

                Entity from entity set [Shippers], key [<Key=ShipperID,Value=3>]

                Entity from entity set [Shippers], key [<Key=ShipperID,Value=10>]
                Entity from entity set [Shippers], key [<Key=ShipperID,Value=11>]
        Dumping objects in state [Added]
        Dumping objects in state [Deleted]
        Dumping objects in state [Modified]

Which shows that our 2nd query now does indeed pick up the "New Company" record and our ObjectStateManager now knows that we have 5 Unchanged entries and none in the Added state.

Note, I'm not 100% sure at this point about whether I should be calling SaveChanges(true) or not - I've a feeling that I should but it goes no further than that right now :-)

What if we go a little further than just inserting a single record and insert something that has a relationship? For example;

   using (NorthwindContext ctx = new NorthwindContext("Name=NorthwindEntities"))
      {
        Customers c = new Customers() { 
          CustomerID = "DEMO1",
          CompanyName = "Acme"
        };
        Orders o = new Orders()
        {          
        };
        c.Orders.Add(o);

        ctx.AddObject("Customers", c);

        DumpObjectStateManager(ctx.ObjectStateManager);

        ctx.SaveChanges(true);

        DumpObjectStateManager(ctx.ObjectStateManager);
      }

Which gives me output;

Dumping Object State Manager
        Dumping objects in state [Detached]
        Dumping objects in state [Unchanged]
        Dumping objects in state [Added]
                Entity from entity set [Customers], key [<Key=Temporary>]
                Entity from entity set [Orders], key [<Key=Temporary>]
        Dumping objects in state [Deleted]
        Dumping objects in state [Modified]


Dumping Object State Manager
        Dumping objects in state [Detached]
        Dumping objects in state [Unchanged]
                Entity from entity set [Customers], key [<Key=CustomerID,Value=DEMO1>]
                Entity from entity set [Orders], key [<Key=OrderID,Value=11079>]

        Dumping objects in state [Added]
        Dumping objects in state [Deleted]
        Dumping objects in state [Modified]

So we can see that only adding that Customers instance caused a navigation of its relationships to pull in the Orders instance as well and that, prior to the call to SaveChanges they exist in the Added state with temporary keys (interesting to me as CustomerID in Northwind isn't actually a generated value - i.e. I provided the key) and after the call to SaveChanges they are now properly part of the EntitySet in the Unchanged state.


Posted Mon, Aug 27 2007 4:39 PM by mtaulty

Comments

Mike Taulty's Blog wrote Entity Framework - Object Services Level. Updating and ObjectStateManager.
on Mon, Aug 27 2007 4:41 PM
Following on from the previous post I wanted to apply a similar approach with updating data. If I go...
Mike Taulty's Blog wrote Entity Framework - Object Services Level. Deleting and ObjectStateManager.
on Mon, Aug 27 2007 4:43 PM
Following the general theme of the last couple of posts (here and here), I thought I'd carry on and experiment...
Guy Burstein's Blog wrote ADO.Net Entity Framework Beta 2 is available
on Mon, Aug 27 2007 10:36 PM
ADO.Net Entity Framework Beta 2 is available The ADO.Net Entity Framework bits for Visual Studio 2008
Mike Taulty's Blog wrote ADO.NET Entity Framework - Bringing Together A Few Previous Posts
on Wed, Aug 29 2007 5:38 PM
This is just a convenience - links to the posts that I've made so far around beta 2 of the ADO.NET Entity...
Entity Framework from Mike Taulty « vincenthome’s Software Development wrote Entity Framework from Mike Taulty &laquo; vincenthome&#8217;s Software Development
on Fri, Sep 7 2007 7:25 AM