NullReferenceException getting navigational property just set (using lazy loading)
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
In the following code a product is created, then an orderline for that product is created.
On line 39 (marked with /\*39\*/) line.Product is set with a non-null value.
On line 40, the line.Product is dereferrenced and results in a NullReferenceException.
This should not be the case. "line.Product" should not be null at this stage.
The project uses an SQLite in-memory database with lazy loading and change tracking proxies.
```
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
public static class Program
{
static OrderContext Context = new OrderContext();
static int prod1Id;
public static void Main(string[] args)
{
Context.Database.EnsureDeleted();
Context.Database.EnsureCreated();
CreateProduct();
AddOrderline();
}
public static void CreateProduct()
{
// Create and store a product with Id=1:
var prod = Context.Products.CreateProxy();
prod.Name = "FooBar";
prod.CatalogPrice = 12.99m;
Context.Products.Add(prod);
Context.SaveChanges();
prod1Id = prod.Id;
Console.WriteLine(prod1Id);
}
public static void AddOrderline()
{
// Get a product:
var prod = Context.Products.Find(prod1Id)!;
// Create orderline:
var line = Context.OrderLines.CreateProxy();
/*39*/ line.Product = prod;
/*40*/ var cp = line.Product.CatalogPrice;
line.OrderPrice = cp;
Context.OrderLines.Add(line);
Context.SaveChanges();
Console.WriteLine(line.OrderPrice);
}
}
public class OrderContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var connection = new SqliteConnection("Filename=:memory:");
connection.Open();
optionsBuilder.UseSqlite(connection);
optionsBuilder.UseChangeTrackingProxies();
optionsBuilder.UseLazyLoadingProxies();
}
public virtual DbSet OrderLines { get; set; }
public virtual DbSet Products { get; set; }
}
public class OrderLine
{
[Key]
public virtual int Id { get; set; }
public virtual int ProductId { get; set; }
[ForeignKey(nameof(ProductId))]
public virtual required Product Product { get; set; }
public virtual decimal OrderPrice { get; set; }
}
public class Product
{
[Key]
public virtual int Id { get; set; }
public virtual required string Name { get; set; }
public virtual decimal CatalogPrice { get; set; }
}
```
Target framework: .NET 8.0
Included package references:
```
all
runtime; build; native; contentfiles; analyzers; buildtransitive
```
Exception thrown:
```
Unhandled exception. System.NullReferenceException: Object reference not set to an instance of an object.
at Program.AddOrderline3() in C:\Stuff\EfCoreLazyAddOrder\EfCoreLazyAddOrder\Program.cs:line 40
at Program.Main(String[] args) in C:\Stuff\EfCoreLazyAddOrder\EfCoreLazyAddOrder\Program.cs:line 17
```
Contributor guide
Assessment
This issue has not been assessed yet.