2009-01-31 4 views
15

У меня этот код: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, поэтому я не знаю, что конкретно имеет значение null при оценке. Что дает?

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

+0

Возможный дубликат (HTTP: // StackOverflow. ком/вопросы/4660142/что-это-NullReferenceException-и-как-делать-я-фикс-я t) – Nasreddine

+0

@ Насреддин: Я не вижу, как вопрос, заданный в 2009 году, может быть дублированием вопроса, заданного в 2011 году. – tsilb

ответ

4

Got it.

Вместо того, чтобы создавать класс, который наследуется от класса 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 обработчика, но, кажется, делают работу, костяк меня раньше. Работает отлично теперь :)

+0

thx: D LINQ костяк меня таким же образом;) – SpoBo

+4

Я думаю, что вызов автогенерированного конструктора (с помощью: this()) лучше, чем копирование в него. – svick

+0

thkx для вас ответ. Все еще неясно, почему мы должны расширить класс DataContext с помощью частичного класса. Я попытался сделать это, 'public class IP: DC.IP { public IP(): base() {...} }' что здесь неправильно? – mehul9595

1

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

+0

OK; он никогда не попадает в эту строку, потому что исключение выбрано для InsertOnSubmit. – tsilb

+0

Это не решение, но +1 для обеспечения чего-то полезного, которого я не знал. – tsilb

2

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

+0

Нет, я создал DataContext, перетащил и вытащил таблицы из Data Connections и прошел конструктор ... umm, construction. SELECT все работает нормально. – tsilb

+0

Это не было решением, но +1, поскольку он управлял мной в общем направлении, обеспечивающем решение. – tsilb

5

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

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

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

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

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

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

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

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 
    } 
} 
Смежные вопросы