LINQ InsertOnSubmit: исключение NullReferenceException

У меня есть этот код:

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) { ... }
}

При попытке InsertOnSubmit (ip) я получаю исключение NullReferenceException (ссылка объекта не установлена ​​в экземпляр объекта). dc не равен нулю; ip и все свойства ip не равны нулю; хотя некоторые из них пусты.

VS2008 не позволит мне входить в InsertOnSubmit, поэтому я не могу понять, что конкретно является нулевым при оценке. Что дает?

Примечание. Я проверил, и все Linq.EntitySets, созданные отношениями FK, присутствуют и не являются нулевыми.

Ответы

Ответ 1

Получил это.

Вместо создания класса, который наследуется от класса DataContext, я расширяю класс DC с частичным классом на уровне Business Logic. Оттуда я могу добавить любые конструкторы и методы, которые я желаю.

В этом случае необходимо скопировать код из существующего (автоматически сгенерированного) конструктора:

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(); }

Не уверен, что в этом обработчике OnCreated, но, похоже, он делает работу, которая меня кость раньше. Хорошо работает сейчас:)

Ответ 2

На самом деле лучше добавить вызов к вашему конструктору, который также вызывает общий конструктор, например:

public IP(string address) : this() {
...
}

Ответ 3

Так как конструктор по умолчанию уже инициализирует base(), this._Sessions и запускает метод OnCreated, все, что вам нужно сделать в вашем расширенном конструкторе, это:

public IP(string address) : this()
{
    Address = address;
    Domain = "";
    Notes = "";
    FirstAccess = DateTime.Now;
    LastAccess = DateTime.Now;
}

Ответ 4

Является ли это создателем конструктора DataContext или вашим собственным ручным. Я подозреваю, что таблица IPs не может быть создана при попытке использовать InsertOnSubmit(). Я не вижу, как это произойдет с созданным конструктором DataContext, но я, как известно, забыл инициализировать мои коллекции время от времени в моем собственном коде.

Ответ 5

Вы можете попытаться понять, что происходит, какие изменения будут сделаны, если вы поместите точку останова непосредственно перед SubmitChanges и быстро просмотрите dc. GetChangeSet().

Ответ 6

У меня была немного отличная ситуация, чем у меня, но по той же причине получила ту же ошибку. Я написал новые конструкторы в частичном классе для своих сущностей базы данных, а затем попытался использовать результирующие объекты в вызовах InsertOnSubmit.

Ни один из этих ответов не помог мне напрямую, но я смог выяснить, что они получают, прочитав все из них.

Автоматически сгенерированный конструктор без параметров для объекта делает вещи, которые должны произойти для InsertOnSubmit, чтобы работать, поэтому, если вы перегружаете конструктор - например, me - или наследуете от класса - как и спрашиваете - вы нужно вызвать базовый конструктор из вашего нового конструктора, например:

public partial class Entity {
    public Entity( Type parameter ) : this() {
        // do things with the parameter
    }
}

или

public class SubEntity: Entity {
    public SubEntity( Type parameter ) : base() {
        // do things with the parameter
    }
}