1

I would like to be able to subclass automatically generated LINQ to SQL Data Classes and save changes to said objects.

For example, if I have a table Client in my database, I can create ClientBO that extends class Client, and adds behaviors like GenerateInvoice() or whatever. Everything works fine until I want to update values in a subclass or insert a new record. Such changes are (predictably?) discarded. Is there something I'm missing, or am I violating a LINQ to SQL or OO principle by creating these subclasses in the first place?

Following are simplified examples of my code:

public class ClientBO : Client
{
    public ClientBO( Client source ) : base()
    {
        FirstName = source.FirstName;
        Lastname = source.LastName;
        // ... etc ...
    }
}

List<ClientBO> clientList = 
    ( from client in DatabaseContext.Clients select new ClientBO( client ) ).ToList();

clientList[ someIndex ].SomeField = NewValue;
MyDatabaseContext.SubmitChanges();
Bob Kaufman
  • 12,864
  • 16
  • 78
  • 107

2 Answers2

4

The problem is that the object you are changing is no longer the same object as gotten from the data store.

The DataContext tracks changes to all objects it have attached. But as you never change the "source"-object as you refer it to, the data context is never notified of the change

I would suggest you to make your ClientBO a partial class of the Client instead (of course, renaming it to Client). All Linq-To-Sql classes are generated as partial and thus you can easily extend them this way

Like this:

public partial class Client
{
    public void GenerateInvoice()
    {
        // ... etc ...
    }
}

List<Client> clientList = MyDatabaseContext.Clients.ToList();

clientList[ someIndex ].SomeField = NewValue;
MyDatabaseContext.SubmitChanges();
Oskar Kjellin
  • 21,280
  • 10
  • 54
  • 93
  • +1 Both yours and Hogan's are excellent approaches which I should have considered in the first place. I'm going with yours because it involves the least changes to my existing infrastructure. – Bob Kaufman May 17 '11 at 20:00
  • +1 i think this is the way to go. You might want to reconsider adding "GenerateInvoice" to the Client class though:) but that is not the point here – Pleun May 18 '11 at 19:43
  • @Pleun - GenerateInvoice() was an abstract example, and an admittedly horrible example at that. – Bob Kaufman May 19 '11 at 16:20
1

I think what you really want here is some extension methods:

http://msdn.microsoft.com/en-us/library/bb383977.aspx

They will look like they are part of the class, but you implement them in a different module. Exactly what you want.

Hogan
  • 69,564
  • 10
  • 76
  • 117
  • +1 Both yours and Oskar's are appropriate. Oskar's involves fewer changes to my existing infrastructure. However I should have been considering this in the first place. – Bob Kaufman May 17 '11 at 20:02