Following the general theme of the last couple of posts (here and here), I thought I'd carry on and experiment with deleting.
static void Main(string[] args)
{
using (NorthwindContext ctx = new NorthwindContext("Name=NorthwindEntities"))
{
Shippers s = ctx.Shippers.First();
ctx.DeleteObject(s);
DumpObjectStateManager(ctx.ObjectStateManager);
DumpShippers(ctx.Shippers);
}
}
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);
}
}
Now, a couple of interesting things here. Firstly, when we hit the DumpObjectStateManager we get;
Dumping Object State Manager
Dumping objects in state [Detached]
Dumping objects in state [Unchanged]
Dumping objects in state [Added]
Dumping objects in state [Deleted]
Entity from entity set [Shippers], key [<Key=ShipperID,Value=1>]
Dumping objects in state [Modified]
Dumping
Shipper id [1], name [Speedy Express], tel [Unlisted]
Shipper id [2], name [United Package], tel [(503) 555-3199]
Shipper id [3], name [Federal Shipping], tel [(503) 555-9931]
So, we're in a slightly odd situation here. The ObjectStateManager knows that we've deleted the row but the row still appears in the query that we execute. Naturally, if we commit those changes to the store;
static void Main(string[] args)
{
using (NorthwindContext ctx = new NorthwindContext("Name=NorthwindEntities"))
{
Shippers s = ctx.Shippers.Where("it.shipperid = 12").First();
ctx.DeleteObject(s);
ctx.SaveChanges(true);
DumpObjectStateManager(ctx.ObjectStateManager);
DumpShippers(ctx.Shippers);
}
}
Gives the output;
Dumping Object State Manager
Dumping objects in state [Detached]
Dumping objects in state [Unchanged]
Dumping objects in state [Added]
Dumping objects in state [Deleted]
Dumping objects in state [Modified]
Dumping
Shipper id [1], name [Speedy Express], tel [Unlisted]
Shipper id [2], name [United Package], tel [(503) 555-3199]
Shipper id [3], name [Federal Shipping], tel [(503) 555-9931]
So, what does this say about what you get back from the ObjectStateManager?
- Inserted items will not show up in queries until they've been sent to the store.
- Deleted items will show up in queries until they've been removed from the store.
- Updated values will show up in results from queries whether they've been transmitted to the store or not.
Now, what happens if you delete an entity that is the parent of a relationship such as a customer and their orders?
using (NorthwindContext ctx = new NorthwindContext("Name=NorthwindEntities"))
{
Customers newCustomer = new Customers()
{
CustomerID = "DEMO1",
CompanyName = "Demo Company"
};
Orders newOrder = new Orders();
newCustomer.Orders.Add(newOrder);
ctx.AddObject("Customers", newCustomer);
// Make those changes live in the DB.
ctx.SaveChanges(true);
ctx.DeleteObject(newCustomer);
ctx.SaveChanges(true);
}
This is an interesting one because what happens here is that we update the Order in order to set its CustomerID to null and orphan it away from its owning Customer before we delete it. I can alter that behaviour by changing my CSDL. If I change the CSDL for the relationship to read;
<Association Name="FK_Orders_Customers">
<End Role="Customers" Type="Northwind.Customers" Multiplicity="0..1">
<OnDelete Action="Cascade"/>
</End>
<End Role="Orders" Type="Northwind.Orders" Multiplicity="*" />
</Association>
then the same piece of code causes the Order to be deleted rather than orphaned. There seem to be three values for <OnDelete Action=""/> - namely, Restrict, Cascade, None. I can't determine at the time of writing the difference between [Restrict/None] which both seem to orphan the Order.
Posted
Mon, Aug 27 2007 4:43 PM
by
mtaulty