efcore
efcore copied to clipboard
Nullable object must have a value thrown for a query with DefaultIfEmpty()
Hi, I am getting error "Nullable object must have a value" using the following scenario:
var categories = from c in dbContext.Set<AMOS_ADDRESSCATEGORY>().AsNoTracking()
select new
{
Id = c.ADDRESSCATEGORYID,
Name = c.DESCRIPTION
};
var addresses = (from address in dbContext.Set<AMOS_ADDRESS>().AsNoTracking()
join c in categories on address.ADDRESSCATEGORYID equals c.Id into aC
from category in aC.DefaultIfEmpty()
select new
{
Id = address.ADDRESSID,
Category = category
}).ToArray();
The above scenarion works pefectly using EF Standard and works in EF Core if I change to:
var addresses = (from address in dbContext.Set<AMOS_ADDRESS>().AsNoTracking()
**join c in dbContext.Set<AMOS_ADDRESSCATEGORY>().AsNoTracking()**
on address.ADDRESSCATEGORYID equals c.ADDRESSCATEGORYID into aC
from category in aC.DefaultIfEmpty()
select new
{
Id = address.ADDRESSID,
Category = category
}).ToArray();
Can you help me please? Thanks in advance Luigi
EF Core version: 8.0.0-preview.4.23259.3 Database provider: Microsoft.EntityFrameworkCore.SqlServer Target framework: NET 6.0 Operating system: IDE: Visual Studio 2022 17.4
This issue is lacking enough information for us to be able to fully understand what is happening. Please attach a small, runnable project or post a small, runnable code listing that reproduces what you are seeing so that we can investigate.
Note for triage: we don't handle assigning null to the anonymous type after calling DefaultIfEmpty
, but it seems like this should work, and it works in LINQ-to-Objects.
Hi @ajcvickers I believe it has same issue with non anonymous type. Example:
var categories = from c in dbContext.Set<AMOS_ADDRESSCATEGORY>().AsNoTracking()
select new Category
{
Id = c.ADDRESSCATEGORYID,
Name = c.DESCRIPTION
};
var addresses = (from address in dbContext.Set<AMOS_ADDRESS>().AsNoTracking()
join c in categories
on address.ADDRESSCATEGORYID equals c.Id into aC
from category in aC.DefaultIfEmpty()
select new
{
Id = address.ADDRESSID,
Category = category
}).ToArray();
Hi, Has been solved in version 8 ? I tested and seems still present.. Thanks in advance
This issue is in the Backlog milestone. This means that it is not fixed in EF Core 8.0. We will re-assess the backlog and consider this item in the upcoming planning. However, keep in mind that there are many other high priority features with which it will be competing for resources. Make sure to vote (👍) for this issue if it is important to you.
Hi, thanks for prompt reply. I believe that this issue should be with high priority because fails on a simple left join operation. Anyway thanks for suggestion
I have the same exception using a simple group by statement, I think the root cause might be the same. You can run this in roslyn pad to reproduce.
#r "nuget: Microsoft.EntityFrameworkCore.Sqlite,8.0.0"
#r "nuget: Microsoft.EntityFrameworkCore,8.0.0"
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
await using var ctx = new Context();
await ctx.Database.EnsureDeletedAsync();
await ctx.Database.EnsureCreatedAsync();
ctx.Steps.Add(new Step
{
Id = 5
});
await ctx.SaveChangesAsync();
await ctx.Steps
.GroupBy(e => new
{
e.Planned
}).ToListAsync();
public class Context : DbContext
{
public DbSet<Step> Steps { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseSqlite(Environment.ExpandEnvironmentVariables("DataSource=%USERPROFILE%/Desktop/test_db.sqlite"))
.LogTo(Console.WriteLine, LogLevel.Information)
.EnableSensitiveDataLogging();
}
public class Step
{
[Key]
public int Id { get; set; }
public DateTime? Planned { get; set; }
}
Hi, any news on the above? Thanks in advance
This issue is in the Backlog milestone. This means that it is not planned for the next release (EF Core 8.0). We will re-assess the backlog following the this release and consider this item at that time. However, keep in mind that there are many other high priority features with which it will be competing for resources. Make sure to vote (👍) for this issue if it is important to you.
I will "vote" it for sure but let me say that this issue is really a bug for anyone want to outer join tables.
Regards Luigi
We're also experienced the issue on a piece of code very similar to @Luigi6821 , I'll keep an eye on this issue. Can anybody explain how can we vote this one up?
Same issue here, how can we vote?
@geraparra vote (thumbs up 👍) in the top comment of the issue.
Hi, I am testing version 9 preview 9.0.0-preview.3.24172.4 and still the error is present. Honestly I am buffled on how this "pillar" functionality is not working and how any other can use EF core without having it fixed.
Yes, this issue is still in the backlog milestone - we haven't yet fixed it. Ultimately, it has only 10 upvotes, meaning that very few users run into it, and therefore it's not at the top of our priority list.
Yes, this issue is still in the backlog milestone - we haven't yet fixed it. Ultimately, it has only 10 upvotes, meaning that very few users run into it, and therefore it's not at the top of our priority list.
I can't believe in users that do not use outer JOIN. There is some workaround?
This issue has been present since EF Core 5+until now
This is a breaking change when upgrading from EFCore 3.1 to EFCore 5, but it is not mentioned in the Microsoft documentation, causing widespread errors in our production environment.
@ajcvickers @roji Can you fix it ?
static void Main(string[] args)
{
//Table AppointmentOrder only has 1 record, while table AppointmentDetail has no data.
var connectionString = $"Data Source=(localdb)\\ProjectModels;Initial Catalog=eftest;Integrated Security=True;Connect Timeout=30;Encrypt=False;Trust Server Certificate=False;Application Intent=ReadWrite;Multi Subnet Failover=False";
var builder = new DbContextOptionsBuilder<SqliteContext>();
builder.UseLoggerFactory(LoggerFactory.Create(builder => builder.AddConsole()));
builder.UseSqlServer(connectionString);
var dbContext = new SqliteContext(builder.Options);
var query = from a in dbContext.AppointmentOrder
join cc in dbContext.AppointmentDetail on a.AppointmentId equals cc.AppId into ccQuery
from c in ccQuery.DefaultIfEmpty()
select new
{
a.AppointmentId,
c.DetailCount
};
var list = query.ToList();
Console.ReadLine();
}
public class AppointmentOrder
{
public int AppointmentId { get; set; }
public string AppointmentNo { get; set; }
}
public class AppointmentDetail
{
public int AppId { get; set; }
public int DetailCount { get; set; }
}
I am using ((int?)c.DetailCount).GetValueOrDefault()
instead of it
But we need to make changes one by one