none
Implementing extensibility methods break LINQ to SQL RRS feed

  • Question

  • Hi all,

    I have a database which I access through LINQ to SQL. I want to do something whenever some record is created, updated or deleted. In order to do this, I implemented the extensibility methods defined in my designer.cs file. To be clear, I'm talking about the Insert*(* instance), Update*(* instance) and Delete*(* instance) methods, where * is the name of my tables.

    Sure enough, the correct methods get called when I commit changes. However, the corresponding change does not actually happen on the database! It seems like just implementing the partial method is enough to break LINQ to SQL - even if the method does nothing. I don't even know how this would be possible; in theory, the caller of a partial method shouldn't even know whether it's implemented or not...

    Is this a bug? Is there anything that can be done about it?

    Tuesday, August 28, 2012 5:18 PM

Answers

  • Okay, I think I nailed it. The problem is that these "extensibility methods" are not actually designed to extend the functionality, but rather to replace it. Like overriding a virtual function, except that somebody decided subclassing is passé and decided to use partial methods instead. I still don't know how LINQ to SQL can behave differently when a partial method is not implemented versus when it is - maybe it uses reflection.

    As one might suspect, I don't quite agree with this design decision (I mean, this is pretty much the problem subclassing was invented to solve, and they solve it with partial methods instead...), but I can live with it. I just need a way to invoke the default behaviour. If this was done through subclassing, I'd just call base.InsertWhatever, but since it's done in a weird way I can't do that. I guess that I need to call ExecuteDynamicInsert, but I can't find any documentation explicitly stating that LINQ to SQL calls ExecuteDynamicInsert (and only ExecuteDynamicInsert) if InsertWhatever is not implemented.

    Anyway, I've tried putting ExecuteDynamicInsert in my extensibility method and it appears to work. I can't be sure that I'm not skipping some optimisation or validation step by doing so, though. :-/

    • Marked as answer by Zappo1980 Wednesday, August 29, 2012 7:13 AM
    Wednesday, August 29, 2012 7:13 AM

All replies

  • I am surprised you can even run with the code within the partial method.  When I put an statement into a partial method I get compile errors.

    Error 1 Partial methods must have empty method bodies. C:\My VS Projects\WPF_MasterDetailExample\WPF_MasterDetailExample\CustInvoices.designer.vb 34 25 WPF_MasterDetailExample

    http://www.codeproject.com/Articles/30101/Introduction-to-Partial-Methods

    http://blogs.msdn.com/b/vbteam/archive/2007/03/27/partial-methods.aspx

    Hope this helps

    LS


    Lloyd Sheen

    Tuesday, August 28, 2012 6:07 PM
  • I don't know why you're getting a compile error, but partial methods would be pretty useless if you couldn't put statements in them... maybe you're trying to implement it in more than one place?

    Anyway, the partial method I write runs fine, with or without code. The problem is that LINQ to SQL no longer actually updates the database if the partial method is implemented.

    Wednesday, August 29, 2012 6:50 AM
  • Okay, I think I nailed it. The problem is that these "extensibility methods" are not actually designed to extend the functionality, but rather to replace it. Like overriding a virtual function, except that somebody decided subclassing is passé and decided to use partial methods instead. I still don't know how LINQ to SQL can behave differently when a partial method is not implemented versus when it is - maybe it uses reflection.

    As one might suspect, I don't quite agree with this design decision (I mean, this is pretty much the problem subclassing was invented to solve, and they solve it with partial methods instead...), but I can live with it. I just need a way to invoke the default behaviour. If this was done through subclassing, I'd just call base.InsertWhatever, but since it's done in a weird way I can't do that. I guess that I need to call ExecuteDynamicInsert, but I can't find any documentation explicitly stating that LINQ to SQL calls ExecuteDynamicInsert (and only ExecuteDynamicInsert) if InsertWhatever is not implemented.

    Anyway, I've tried putting ExecuteDynamicInsert in my extensibility method and it appears to work. I can't be sure that I'm not skipping some optimisation or validation step by doing so, though. :-/

    • Marked as answer by Zappo1980 Wednesday, August 29, 2012 7:13 AM
    Wednesday, August 29, 2012 7:13 AM