2009-01-31 14 views
15

tengo este código: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) { ... } 
} 

al intentar InsertOnSubmit (ip), consigo un NullReferenceException (Referencia a objeto no establecida como una instancia de un objeto). dc no es nulo; ip y todas las propiedades de ip no son nulas; aunque algunos están vacíos.

VS2008 no me deja entrar en InsertOnSubmit, por lo que no tengo forma de saber qué es específicamente nulo cuando se evalúa. ¿Lo que da?

Nota: He comprobado, y todos los Linq.EntitySets creados por las relaciones FK están presentes y no son nulos.

+0

duplicado Posible de (http: // stackoverflow. com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-i t) – Nasreddine

+0

@Nasreddine: No veo cómo una pregunta hecha en 2009 podría ser un duplicado de una pregunta hecha en 2011. – tsilb

Respuesta

4

Lo tengo.

En lugar de crear una clase que herede de la clase DataContext, extiendo la clase DC misma con una clase parcial en la capa de lógica de negocios. Desde allí puedo agregar cualquier constructor y método que desee.

En este caso, es necesario recurrir a copiar el código desde el constructor existente (autogenerado):

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

seguro de lo que hay en ese manejador OnCreated, pero parece estar haciendo el trabajo que deshuesada yo antes. Funciona bien ahora :)

+0

thx: D LINQ me deshuesó de la misma manera;) – SpoBo

+4

Creo que llamar al constructor autogenado (usando: this()) es mejor que copiar y pegarlo. – svick

+0

thkx para su respuesta. Todavía no está claro por qué tenemos que extender la clase DataContext con Class parcial. Intenté hacerlo de esta manera, 'IP de clase pública: DC.IP { IP pública(): base() {...} }' ¿Qué es incorrecto aquí? – mehul9595

1

Puede intentar ver qué está sucediendo, qué cambios se realizarán, si coloca un punto de interrupción justo antes de SubmitChanges, y realiza una observación rápida de dc.GetChangeSet().

+0

OK; nunca llega a esa línea porque la excepción se produce en InsertOnSubmit. – tsilb

+0

Esa no era la solución, pero +1 por proporcionar algo útil que no había conocido. – tsilb

2

Este es un DataContext generado por el diseñador o uno propio creado a mano. Sospecho que la tabla de IP no se puede instanciar en el momento en que prueba su InsertOnSubmit(). No puedo ver cómo sucedería esto con un DataContext generado por un diseñador, pero se sabe que olvido inicializar mis colecciones de vez en cuando en mi propio código.

+0

No, creé un DataContext, arrastré y eliminé las tablas de Data Connections, y pasé por el constructor ... umm, construction. SELECCIONA todo el trabajo bien. – tsilb

+0

Esa no era la solución, pero +1 ya que me guiaba en la dirección general que proporcionaba la solución. – tsilb

5

Desde el constructor por defecto ya se inicializa base(), this._Sessions y se ejecuta el método OnCreated, todo lo que tiene que hacer en su constructor extendida es la siguiente:

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

En realidad es mejor añadir una llamada a su constructor que también se llama al constructor genérico como:

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

que tenía una situación un poco diferente que el autor de la pregunta, pero tiene el mismo error por las mismas razones. Escribí nuevos constructores en una clase parcial para mis entidades de base de datos, luego traté de usar los objetos resultantes en llamadas InsertOnSubmit.

Ninguna de estas respuestas me ayudó directamente, pero pude descubrir en qué estaban obteniendo después de leer todas ellas.

El constructor sin parámetros autogenerado para la entidad hace las cosas que deben suceder para que InsertOnSubmit funcione, por lo que si sobrecarga el constructor, como yo, o hereda de la clase, como el asker, necesita para llamar al constructor base de su nuevo constructor, así: [? ¿Qué es un NullReferenceException y cómo lo arreglo]

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

o

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