LINQ InsertOnSubmit: NullReferenceException - PullRequest
       21

LINQ InsertOnSubmit: NullReferenceException

16 голосов
/ 31 января 2009

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

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

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

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

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

Ответы [ 6 ]

10 голосов
/ 15 октября 2009

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

public IP(string address) : this() {
...
}
5 голосов
/ 10 февраля 2009

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

public IP(string address) : this()
{
    Address = address;
    Domain = "";
    Notes = "";
    FirstAccess = DateTime.Now;
    LastAccess = DateTime.Now;
}
5 голосов
/ 01 февраля 2009

Понял.

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

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

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 голосов
/ 31 января 2009

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

1 голос
/ 23 сентября 2014

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

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

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

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
    }
}
1 голос
/ 31 января 2009

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

...