Page 1 of 1

EF Core 3 query property of nullable reference type as owned type throws exception

Posted: Wed 18 Dec 2019 13:15
by laurensb
Given an entity with a nullable reference type:

Code: Select all

public class BeastRider
{
	public long Id { get; private set; }

	public string RiderName { get; private set; }

	public Beast? Beast { get; private set; }
}
Which is mapped as an owned type:

Code: Select all

modelBuilder.Entity<BeastRider>().OwnsOne(_ => _.Beast,
                ba =>
                {
                    ba.Property(beast => beast.Name).HasColumnName("BEAST_NAME");
                });
I am unable to perform string queries such as "StartsWith" on a string property of the owned type:

Code: Select all

// This works
var khalDrogo = await context.Set<BeastRider>()
	.FirstOrDefaultAsync(_ => _.Beast != null && _.Beast.Name == "Khal drogo");

// This fails with 'System.InvalidOperationException: Null TypeMapping in Sql Tree'
var khals = await context.Set<BeastRider>()
	.Where(_ => _.Beast != null && _.Beast.Name.StartsWith("Khal"))
	.ToArrayAsync();
For EF Core 2.1 this was recently fixed after my bug report here.

A repository reproducing the bug can be found here.

Reproducible for:
  • Devart.Data.Oracle.EFCore: 9.9.887
  • Microsoft.EntityFrameworkCore.Relational: 3.0.1 & 3.1.0
  • .NET Core SDK versions: 3.0.101 & 3.1.100
  • .NET Core Runtime versions: 3.0 & 3.1
Furthermore, the query which does work using simple comparison instead of string operations generates the following SQL query:

Code: Select all

     SELECT "b".ID,
            "b".RIDER_NAME,
            "t".ID ID1,
            "t".BEAST_NAME
       FROM BEAST_RIDER "b"
            LEFT JOIN
            (SELECT "b0".ID, "b0".BEAST_NAME, "b1".ID ID0
               FROM BEAST_RIDER "b0"
                    INNER JOIN BEAST_RIDER "b1" ON "b0".ID = "b1".ID
              WHERE "b0".BEAST_NAME IS NOT NULL) "t"
                ON "b".ID = "t".ID
      WHERE "t".ID IS NOT NULL AND ("t".BEAST_NAME = 'Khal drogo')
FETCH FIRST 1 ROWS ONLY
Joining the same table 3 times seems unnecessary and is even worse than my EF Core 2.1 bug report when using owned types in an inheritance hierarchy.

Re: EF Core 3 query property of nullable reference type as owned type throws exception

Posted: Thu 26 Dec 2019 13:37
by Shalex
Thank you for your report. We will investigate both issues and notify you about the result.

Re: EF Core 3 query property of nullable reference type as owned type throws exception

Posted: Sat 28 Dec 2019 12:20
by Shalex
// This fails with 'System.InvalidOperationException: Null TypeMapping in Sql Tree'
var khals = await context.Set<BeastRider>()
.Where(_ => _.Beast != null && _.Beast.Name.StartsWith("Khal"))
.ToArrayAsync();
The bug with throwing the "Null TypeMapping in Sql Tree" error by methods in LINQ query in EF Core 3 is fixed in v9.10.909.

Re: EF Core 3 query property of nullable reference type as owned type throws exception

Posted: Tue 28 Jan 2020 20:19
by Shalex
Furthermore, the query which does work using simple comparison instead of string operations generates the following SQL query:

Code: Select all

     SELECT "b".ID,
            "b".RIDER_NAME,
            "t".ID ID1,
            "t".BEAST_NAME
       FROM BEAST_RIDER "b"
            LEFT JOIN
            (SELECT "b0".ID, "b0".BEAST_NAME, "b1".ID ID0
               FROM BEAST_RIDER "b0"
                    INNER JOIN BEAST_RIDER "b1" ON "b0".ID = "b1".ID
              WHERE "b0".BEAST_NAME IS NOT NULL) "t"
                ON "b".ID = "t".ID
      WHERE "t".ID IS NOT NULL AND ("t".BEAST_NAME = 'Khal drogo')
FETCH FIRST 1 ROWS ONLY
Joining the same table 3 times seems unnecessary and is even worse than my EF Core 2.1 bug report when using owned types in an inheritance hierarchy.
The same LINQ query with https://www.nuget.org/packages/Microsof ... SqlServer/ produces a similar SQL because EF Core engine constructs a complex expression tree for this case:

Code: Select all

      SELECT TOP(1) [b].[ID], [b].[RIDER_NAME], [t].[ID], [t].[BEAST_NAME]
      FROM [BEAST_RIDER] AS [b]
      LEFT JOIN (
          SELECT [b0].[ID], [b0].[BEAST_NAME], [b1].[ID] AS [ID0]
          FROM [BEAST_RIDER] AS [b0]
          INNER JOIN [BEAST_RIDER] AS [b1] ON [b0].[ID] = [b1].[ID]
          WHERE [b0].[BEAST_NAME] IS NOT NULL
      ) AS [t] ON [b].[ID] = [t].[ID]
      WHERE [t].[ID] IS NOT NULL AND ([t].[BEAST_NAME] = N'Khal drogo')

      SELECT [b].[ID], [b].[RIDER_NAME], [t].[ID], [t].[BEAST_NAME]
      FROM [BEAST_RIDER] AS [b]
      LEFT JOIN (
          SELECT [b0].[ID], [b0].[BEAST_NAME], [b1].[ID] AS [ID0]
          FROM [BEAST_RIDER] AS [b0]
          INNER JOIN [BEAST_RIDER] AS [b1] ON [b0].[ID] = [b1].[ID]
          WHERE [b0].[BEAST_NAME] IS NOT NULL
      ) AS [t] ON [b].[ID] = [t].[ID]
      WHERE [t].[ID] IS NOT NULL AND ([t].[BEAST_NAME] IS NOT NULL AND ([t].[BEAST_NAME] LIKE N'Khal%'))

Re: EF Core 3 query property of nullable reference type as owned type throws exception

Posted: Wed 29 Jan 2020 07:12
by laurensb
Thanks for the update, Shalex! It seems the entity framework core team is already aware of this issue since October 9, 2019: https://github.com/dotnet/efcore/issues/18299 so I'm guessing it won't be fixed any time soon.