In my DAL (Data Access Layer) assembly (a LINQ-to-SQL centric assembly) I used to insert object into the database like this
public void CreateMessage(MyApp.Entities.Message message)
{
Message m = new Message(); // this is the LINQ-to-SQL generated Message class not the business entity class
m.UserId = message.UserId;
//... set all the properties accordingly
DataContext ctx = new DataContext();
ctx.InsertOnSubmit(m);
ctx.SubmitChanges();
}
Things worked fine but one day I said : Let’s make use of the partial classes feature available in .NET and simplify the above code. Easier said than done, I’ve created a file called DatabaseExtensions.cs in this DAL assembly and put code like this :
public partial class Message
{
public Message(MyApp.Entities.Message message)
{
this.UserId = message.UserId;
// ... set all the properties accordingly
}
}
then in the other class :
public void CreateMessage(MyApp.Entities.Message message)
{
Message m = new Message(message);
DataContext ctx = new DataContext();
ctx.InsertOnSubmit(m);
ctx.SubmitChanges();
}
after some time I ran the code and forgot all these that I’ve done. At the third line of the CreateMessage method (the one with the InsertOnSubmit call) I always got a NullReferenceException although ctx was not null, m was not null and no property (that I knew about) of m was not null. WTF?!
WTF… WTF…
then it hit me : I supplied a non-default constructor (i.e.: a constructor WITH parameters to the Message class so the default constructor – auto generated by the LINQ designer would NOT be called).
The fix? Ultra-easy (see the bold-brown text below) :
public partial class Message
{
public Message(MyApp.Entities.Message message) : this()
{
this.UserId = message.UserId;
// ... set all the properties accordingly
}
}
Yes, just that : call explicitly the default constructor and all’s well. Clean, simple and working code
HTH.
