16

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.

tsilb
  • 7,977
  • 13
  • 71
  • 98
  • Possible duplicate of [What is a NullReferenceException and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – Nasreddine Oct 04 '15 at 09:09
  • @Nasreddine: I don't see how a question asked in 2009 could possibly be a duplicate of a question asked in 2011. – tsilb Oct 18 '15 at 23:25

6 Answers6

10

Actually it's better to add a call to your constructor that also calls the generic constructor such as:

public IP(string address) : this() {
...
}
Jason Plank
  • 2,336
  • 5
  • 31
  • 40
Max
  • 109
  • 1
  • 2
5

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 :)

tsilb
  • 7,977
  • 13
  • 71
  • 98
  • 4
    I think that calling the auto-genrated constructor (using :this()) is better than copy-pasting it. – svick Sep 28 '09 at 01:32
  • thkx for you answer. Still unclear that why we have to extend the DataContext class with partial Class. I tried doing this way, `public class IP : DC.IP { public IP() : base() { ... } }` what is incorrect here? – mehul9595 Dec 20 '11 at 07:19
  • I figured this out. Inheriting of class from an DataContext Entity class is not supported by Linq To Sql. This link details it out http://connect.microsoft.com/VisualStudio/feedback/details/310798/linq-to-sql-nullreferenceexception-when-attaching-inherited-record – mehul9595 Dec 22 '11 at 07:27
5

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;
}
user64648
  • 51
  • 2
2

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().

Christian C. Salvadó
  • 807,428
  • 183
  • 922
  • 838
2

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.

tvanfosson
  • 524,688
  • 99
  • 697
  • 795
  • Nope, I created a DataContext, dragged & droped the tables over from the Data Connections, and went through the constructor... umm, construction. SELECTs all work just fine. – tsilb Jan 31 '09 at 20:40
  • That wasn't the solution, but +1 as it steered me in the general direction that provided the solution. – tsilb Jan 31 '09 at 21:30
1

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
    }
}
DCShannon
  • 2,470
  • 4
  • 19
  • 32