-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set operations need to consider nullability of columns on both sides #18135
Comments
Mark |
Full repro: using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
namespace EFSampleApp
{
public class Program
{
public static void Main(string[] args)
{
using (var db = new MyContext())
{
// Recreate database
db.Database.EnsureDeleted();
db.Database.EnsureCreated();
// Seed database
db.Add(new Blog
{
Post = new Post()
});
db.Add(new Blog());
db.Add(new Post());
db.SaveChanges();
}
using (var db = new MyContext())
{
// Run queries
var query = db.Blogs
.GroupJoin(db.Posts, b => b.Id, p => p.BlogId, (b, ps) => new { b, ps })
.SelectMany(g => g.ps.DefaultIfEmpty(), (g, p) => new { g.b, p })
.Concat(db.Posts.GroupJoin(db.Blogs, p => p.BlogId, b => b.Id, (p, bs) => new { p, bs })
.SelectMany(g => g.bs.DefaultIfEmpty(), (g, b) => new { b, g.p })
.Where(e => e.b.Equals(null)))
.Select(e => e.b.Id)
.ToList();
}
Console.WriteLine("Program finished.");
}
}
public class MyContext : DbContext
{
private static ILoggerFactory ContextLoggerFactory
=> LoggerFactory.Create(b =>
{
b
.AddConsole()
.AddFilter("", LogLevel.Debug);
});
// Declare DBSets
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// Select 1 provider
optionsBuilder
.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=_ModelApp;Trusted_Connection=True;Connect Timeout=5;ConnectRetryCount=0")
//.UseSqlite("filename=_modelApp.db")
//.UseInMemoryDatabase(databaseName: "_modelApp")
//.UseCosmos("https://localhost:8081", @"C2y6yDjf5/R+ob0N8A7Cgv30VRDJIWEHLM+4QDU5DE2nQ9nDuVTqobD4b8mGGyPMbIZnqyMsEcaGQy67XIw/Jw==", "_ModelApp")
.EnableSensitiveDataLogging()
.UseLoggerFactory(ContextLoggerFactory);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Configure model
}
}
public class Blog
{
public int Id { get; set; }
public Post Post { get; set; }
}
public class Post
{
public int Id { get; set; }
public int? BlogId { get; set; }
public Blog Blog { get; set; }
}
} Generated SQL SELECT [t].[Id]
FROM (
SELECT [b].[Id], [p].[Id] AS [Id0], [p].[BlogId]
FROM [Blogs] AS [b]
LEFT JOIN [Posts] AS [p] ON [b].[Id] = [p].[BlogId]
UNION ALL
SELECT [b0].[Id], [p0].[Id] AS [Id0], [p0].[BlogId]
FROM [Posts] AS [p0]
LEFT JOIN [Blogs] AS [b0] ON [p0].[BlogId] = [b0].[Id]
WHERE [b0].[Id] IS NULL
) AS [t] Here in Union All, cc: @roji |
how should i solve it in ef core 3? class B {public int Id {get;set;} public string forkey {get;set;}} |
@LostAsk we'll work on fixing this for 3.1. The best way around this is in 3.0 is to perform the set operation via client evaluation getting the results of each query independently and then performing the set operation in-memory: var x = context.Blogs.Where(....)
.AsEnumerable().
Concat(context.Posts.Where(...)
.AsEnumerable()); |
OK,Thank you |
FullJoin Method is public static IQueryable<JoinResult<TLeft, TRight>> FullJoin<TLeft, TRight, TKey>( SQL Result: |
@LostAsk I don't see any operation in your code (Union, Concat, Intersection or Except), and the full definition of FullJoin seems to be missing. Please open a new issue with a full runnable code sample, a full stack trace, etc. |
|
@LostAsk can you please open a new issue with the full details - version of EF Core used, full exception including stack trace, etc. |
@roji |
I wrote an Iqueryable assistant, which can correctly generate SQL statements in EF6. The statements generated in EF Core2.2 full join are separate but correct. In EF Core 3 full join, the generated SQL statements are ok, but only report errors.
EF Core3
Message:Data is Null. This method or property cannot be called on Null values.
Stack:
at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull()
at Microsoft.Data.SqlClient.SqlBuffer.get_Int32()
at Microsoft.Data.SqlClient.SqlDataReader.GetInt32(Int32 i)
at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.QueryingEnumerable
1.Enumerator.MoveNext() at System.Collections.Generic.List
1..ctor(IEnumerable1 collection) at System.Linq.Enumerable.ToList[TSource](IEnumerable
1 source)The text was updated successfully, but these errors were encountered: