Reputation: 8037
I have this code:
using DC = MV6DataContext;
using MV6; // Business Logic Layer
// ...
public DC.MV6DataContext dc = new DC.MV6DataContext(ConnectionString);
IP ip = new IP(Request.UserHostAddress);
dc.IPs.InsertOnSubmit(ip);
dc.SubmitChanges();
// in Business Logic layer:
public class IP : DC.IP {
public IP(string address) { ... }
}
Upon attempting to InsertOnSubmit(ip), I get a NullReferenceException (Object reference not set to an instance of an object). dc is not null; ip and all properties of ip are not null; though some are empty.
VS2008 won't let me step into InsertOnSubmit, so I have no way of knowing what specifically is null when being evaluated. What gives?
Note: I have checked, and all Linq.EntitySets created by FK relationships are present and non-null.
Upvotes: 16
Views: 6319
Reputation: 2614
I had a slightly different situation than the asker, but got the same error for the same reasons. I wrote new constructors in a partial class for my database entities, then tried to use the resulting objects in InsertOnSubmit
calls.
None of these answers helped me directly, but I was able to figure out what they were getting at after reading all of them.
The auto-generated parameterless constructor for the entity does things that need to happen for InsertOnSubmit
to work, so if you overload the constructor -- like me -- or inherit from the class -- like the asker -- you need to call the base constructor from your new constructor, like so:
public partial class Entity {
public Entity( Type parameter ) : this() {
// do things with the parameter
}
}
or
public class SubEntity: Entity {
public SubEntity( Type parameter ) : base() {
// do things with the parameter
}
}
Upvotes: 1
Reputation: 109
Actually it's better to add a call to your constructor that also calls the generic constructor such as:
public IP(string address) : this() {
...
}
Upvotes: 10
Reputation: 51
Since the default constructor already initializes base(), this._Sessions and runs the OnCreated method, all you need to do in your extended constructor is this:
public IP(string address) : this()
{
Address = address;
Domain = "";
Notes = "";
FirstAccess = DateTime.Now;
LastAccess = DateTime.Now;
}
Upvotes: 5
Reputation: 8037
Got it.
Rather than creating a class that inherits from the DataContext's class, I extend the DC class itself with a partial class in the Business Logic layer. From there I can add whatever constructors and methods I wish.
In this case, it is neccessary to copy the code from the existing (auto-generated) constructor:
public IP(string address) {
Address = address;
Domain = "";
Notes = "";
FirstAccess = DateTime.Now;
LastAccess = DateTime.Now;
this._Sessions = new EntitySet<Session>(new Action<Session>(this.attach_Sessions), new Action<Session>(this.detach_Sessions));
OnCreated(); }
Not sure what's in that OnCreated handler, but it seems to be doing the work that boned me earlier. Works fine now :)
Upvotes: 5
Reputation: 532515
Is this a designer generated DataContext or your own hand-built one. I suspicious that the IPs table may not be instantiated at the time you try your InsertOnSubmit()
. I can't see how this would happen with a designer-generated DataContext, but I've been known to forget to initialize my collections from time to time in my own code.
Upvotes: 2
Reputation: 827536
You can try to see what's happening, what changes will be done, if you place a breakpoint just before SubmitChanges, and do a quick watch of dc.GetChangeSet().
Upvotes: 2