Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

1.3K
Views
¿Cómo depurar y corregir 'El objeto anulable debe tener un valor' dentro de Entity Framework Core?

Estoy haciendo una proyección en este método:

 public async Task<TradeDetail> Get(int tradeId) { var firstOrDefaultAsync = await context.EvgTGTrade .Where(x => x.IdTrade == tradeId) .Select(trade => new TradeDetail { Id = trade.IdTrade, Code = trade.CdTrade, Description = trade.DeTrade, Comments = trade.DeComentarios, TypeId = trade.IdTipoTrade, BrokerId = trade.EvgTGBrokerTrade.FirstOrDefault().IdBroker, BillingCycleId = trade.IdCicloFacturacion, CounterpartId = trade.IdSujeto, StartDate = trade.FhIni, EndDate = trade.FhFin, SignatureDate = trade.FhFirma, Positions = trade.EvgTGPosicion.Select(pos => new Position { Amount = pos.Cantidad, Code = pos.CdPosicion, Description = pos.DePosicion, LogisticElement = pos.IdElemLogNavigation.DeElemLog, StartDate = pos.FhIni, EndDate = pos.FhFin, FormulaId = pos.IdFormula, Operations = pos.EvgTGOperacionCv.Select(op => new Operation() { TypeId = op.IdTipoOperacion, Fee = op.Fee, Date = op.FhOperacionCv, Price = op.NmPrecio ?? 0, Quantity = op.NmCantidadKwh ?? 0, }), }) }) .FirstOrDefaultAsync(); return firstOrDefaultAsync; }

Recibo una excepción en la primera línea que dice

Microsoft.EntityFrameworkCore.Query: error: se produjo una excepción al iterar sobre los resultados de una consulta para el tipo de contexto 'SampleApp.EF.MyDbContext'. System.InvalidOperationException: el objeto que acepta valores NULL debe tener un valor.

Inspeccioné la excepción y el seguimiento de la pila y no dice nada sobre cuál es el objeto problemático. Ni idea de lo que está mal.

Entonces, ¿hay algún método para saber qué propiedad genera el conflicto? Estoy seguro de que es una discrepancia entre las columnas de propiedades, pero ¿qué sucede si tiene muchas propiedades? ¡Es bastante doloroso!

Actualizar

Ya he solucionado el problema. Se debió a un intento de asignar un valor nulo a una propiedad en mi modelo que no admitía valores NULL.

Dicho esto, esta pregunta no se trata de esta solución concreta, sino de encontrar una forma general de depurar este tipo de situaciones (esta excepción) que son bastante comunes. En mi humilde opinión, el mensaje de excepción es demasiado vago. No proporciona ninguna información útil de la propiedad en conflicto.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Puede haber dos respuestas.

En primer lugar , esto puede deberse probablemente a que su consulta devuelve NULL y el modelo no acepta nulo.

La segunda solución puede ser , si está utilizando tipos anónimos, intente encasillar el resultado de la consulta en un tipo anulable.

p.ej

 Id = (int?) op.Id,

¿Cómo encontrar qué propiedad devuelve NULL?

Puede habilitar SQL Profiler y verificar la consulta SQL que se está ejecutando. Copie la consulta en SSMS y vea qué valores son NULL.
Esto puede ser útil para que decida si realmente necesita un encasillado anulable O si desea cambiar la consulta en sí.

Hay un problema en GitHub en esta página .

Actualización: 05 de julio de 2021: ¿Cómo encontrar qué propiedad devuelve NULL?

Puede usar la función de registro simple (introducida en EF core 5.0) llamando al método EnableDetailedErrors . El siguiente ejemplo de código muestra cómo configurar el registro simple para mostrar registros en la consola y también habilita errores detallados. Si no desea mostrar los registros en la consola, puede pasar un delegado de acción en la llamada LogTo, que acepta una cadena como parámetro. Este delegado puede escribir registros en cualquier destino de su elección.

Consulte la documentación para obtener más detalles.

 protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder .LogTo(Console.WriteLine) .EnableDetailedErrors();
over 4 years ago · Santiago Trujillo Report

0

Quiero agregar a la respuesta de @ Manoj-Choudhari que me ayudó a localizar un problema que comenzó después de actualizar de EF Core 3.x a EF Core 5.x.

Tuve una consulta como esta: (Elemento [1] -> Categorías [0..n] -> Padre [1], las claves son enteros)

 from item in ctx.Items from ixc in item.Categories.DefaultIfEmpty() /* Left join */ let parent = ixc.Parent select new { itemId = item.Id, parentId = parent.Id }

Esto falla con el mismo error "El objeto anulable debe tener un valor" si la navegación a "principal" termina siendo nula. Lo que observé diferente en el comportamiento entre EFC3 y EFC5 es el padre. ¿La parte de identificación de la proyección solía inferirse automáticamente como int? porque parecía entender que el padre podría ser nulo. Parece que tiene que ser más explícito con EF Core 5 y convertir los tipos asignados al tipo anulable manualmente.

 from item in ctx.Items from ixc in item.Categories.DefaultIfEmpty() /* Left join */ let parent = ixc.Parent select new { itemId = item.Id, parentId = (int?)parent.Id }

La forma antigua probablemente era más una hazaña, y es mejor ser específico ahora.

Editar: el equipo de EF Core es consciente de este comportamiento: https://github.com/dotnet/efcore/issues/22517

over 4 years ago · Santiago Trujillo Report

0

Por lo general, hasta donde yo sé, no tiene una forma más rápida de encontrar cuál es exactamente el campo que está causando el problema.

Lo que puedes hacer mirando tu caso, es:

1 - Mire la consulta que está haciendo y verifique si está devolviendo los datos necesarios. Si eso está sucediendo bien, entonces probablemente la consulta podría devolver un valor nulo, y su modelo no lo acepta (y viceversa).

2 - Si el primer elemento funciona correctamente, intente observar las otras iteraciones que está realizando en el modelo. Por ejemplo: está haciendo Positions.Select(), así que verifique si las posiciones y las demás cosas que provienen del modelo de posiciones están bien.

3- Si no estás cien por ciento seguro de lo que es el campo. Simplemente coloque un tipo anulable para cada campo en el que esté haciendo un linq. Ejemplo: BrokerId = trade.EvgTGBrokerTrade.FirstOrDefault().IdBroker, puede agregar un signo de interrogación para asegurarse de que el campo no bloquee su aplicación.

4 - Mire las tablas que crea en la base de datos, probablemente tendrá la información de los campos si son anulables o no. Luego, puede modificar su modelo del código.

Estas son las cosas que te sugiero

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!