Homepage | About Me | Testing ASP.net Book | Best Blog Posts | Personal Projects | Follow me on Twitter | GitHub | SlideShare | RSS
Blog.BenHall.me.uk

Partial Methods in Linq

Sunday, July 29, 2007

Following on from my previous post, I noticed Linq takes advantage of the Partial Methods feature in the language so I thought I would take a closer look.

Within VS Beta 2, the DataContext and database objects contain a number of partial methods to allow you to hook into various methods which are called at certain points within the execution.  All of the definitions are in the datacontext.designer.cs file in a region called Extensibility Method Definitions.

The standard methods included within the data context are:

  • partial void OnCreated();
  • partial void InsertCustomer(Customer instance);
  • partial void UpdateCustomer(Customer instance);
  • partial void DeleteCustomer(Customer instance);

OnCreated() is called when the DataContext object is created, while the others are called on SubmitChanges().  Once SubmitChanges() are called, the DataContext will start processing any changes and calling the methods, if they have been implemented.  HOWEVER I found that if you extend one of the methods, then the action would never be passed to the database. This must be a bug, so something to be aware of.  It might be by design and you use this to override the logic - its not very clear.  If they do override the functionality and its not a bug, I don't like the fact that there is no distinction between a method which is a hook and a method which overrides functionality. If it was something like partial override void .... then it would be a lot better that how it is at the moment.

The database entities also have extension points.

  • partial void OnLoaded();
  • partial void OnValidate();
  • partial void OnCreated();
  • partial void OnOrderIDChanging(int value);
  • partial void OnOrderIDChanged();

These partial methods are a little bit more interesting.  OnCreated is called when an object is initialised.  When loading from a database, OnCreated is called first, then OnLoaded is called.  OnXChanging() is called when the property is changed, just before the value is stored in the internal variable, not when SubmitChanges is called. OnXChanged() is called after the value is stored.

The most important method is OnValidate() which is called just before the action is passed to the database.  Here, you can add custom/business logic to verify that the object (can access everything as you are inside the object, for example this.OrderID) is correct and valid before being saved.  If there is a problem, you can throw an exception and catch it by putting a try/catch around db.SubmitChanges(). Very useful feature.

 

All of the code I wrote can be found here : C# Sample Code

Technorati Tags: , ,

Labels: , ,

Blogger comments

At 8:58 AM, Anonymous Henk Manders said...
You talk about a bug when extending these methods:

partial void InsertCustomer(Customer instance);
partial void UpdateCustomer(Customer instance);
partial void DeleteCustomer(Customer instance);

It actually is not a bug. What you need to do is calling one of these methods:

this.ExecuteDynamicInsert(instance);
this.ExecuteDynamicUpdate(instance);
this.ExecuteDynamicDelete(instance);

For example:

partial void InsertCustomer(Customer instance)
{
// your code here
this.ExecuteDynamicInsert(instance);
// your code here
}

Good luck!    
At 9:14 AM, Blogger Ben Hall said...
Hi,

Thanks for the comment.

Yes, after feedback on a connect issue I realise the intented use of this. I should have updated the post. Sorry.

I spoke about this a bit more on this post
http://blog.benhall.me.uk/2007/08/how-linq-knows-if-partial-method-has.html

Thanks

Ben    
It helped me a lot! great!
thank you! Detailed as much as it have to be. Frankly, better then scottgu :)