I always tend to use LINQ to SQL (L2S) in smaller projects rather than Entity Framework (EF), it’s more lightweight and provides faster development for projects of this scope. Of course, for more robust system I would go with EF because of the better control and the relations between the context objects. If you like to go more into details on this read this topic: L2S vs Ef.
Inheritance is much easier to implement in EF but it can also be done in L2S although in a not very clean way, at least not that I know of. Here I’ll show you how can you add a base class to the L2S entities that can be used for auditing, creating domain events or whatever behavior that you want to achieve across all entities.
How to create L2S table mapped classes
For this demonstration I’ve created sample database with two very simple tables Employees and Animals and create mapped classes for them and show you also very simple usage.
Next thing that we need to do is to add new .dbml in our project. We need to add new “LINQ to SQL Classes” that will create new .dbml file that I named Zoo.dbml.
If we double click this file on our solution explorer view a designer screen will be opened and we can drag-and-drop the tables that we want to be mapped. We need to open the “SQL Server Object Explorer”, open the database where these tables are created and make the drag-and-drop.
That is how easy is to create the table mapped classes in L2S.
In the background the classes that are created for the tables implement INotifyPropertyChanging and INotifuPropertyChanged interfaces and have no base class.
Using these classes is very simple and here is example code hot to make few inserts in the newly created database in nice clean OO way.
In many scenarios/projects these classes will be enough as they are and no need of further modifications. But what should we do if we need to apply some common behavior to all classes?
That is something that I’ll demonstrate next, adding base class and inheritance for our database “models” via practical (but not very useful in the real world) example.
Adding base classes in table mapped classes and data context
In this sample I’ll demonstrate how to add base classes to our data context and table mapped classes, I’ll add the option for adding messages to this classes that will be written in a log file only if the changes are successful. For example we can add messages in the objects on when we they created or by what method or user.
Although, this might not be very useful for real projects it’s very nice example on how can you add base classes and how can you use them. The end purpose in some of my next post would be demonstration of proper implementing of Domain Events which are very important if you are using DDD (Domain Driven Development) and Clean Architecture.
Let’s add the base classes without the logic implementation. The BaseContext class needs to inherit from the DataContext class and we need to implement the two constructors that the designer is using for creating the classes.
Also we’re going to add the BaseEntity class that we are going to use as a base class for the entities (table mapped classes)
Next thing we need to do is to open the dbml file with some xml/text editor and add the inheritance attributes. For this purpose I’m using Notepad++.
We need to set the classes that we created to be base classes for the context and all the entities that are automatically created, so we are adding these attributed in the Database node.
EntityBase = “BaseEntity” – for the base class of the entities
BaseType = “BaseContext” – for the base context
If we open the .cs file we’ll notice that our classes still don’t inherit from the base classes that we created. In order to re-create the code just move some of the tables in the visual designer to force this behavior.
If we do that we can notice that now our entities inherit from our base classes.
Note that after you manually edit the dbml every other attempt to add new objects in the designer you can get this error
to resolve this, just delete the connection node from the dbml xml and try to add the object/table again.
Implementing behavior in the base classes
As I mentioned before, we are going to implement messaging functionality in the base entities that will allow us to write some messages regarding the entities but only after successful database update completion.
So in our BaseEntity we are adding Messages collection and AddMessage method that will allow us to add messages to that collection.
Also we need to override the SubmitChanges method in the BaseContext to handle this messages and write them to a log file if the completion is successful.
So if we now add some messages in the entities that we create/update then these messages will be written in a log file if the db submit is successful.