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

Discussion of open issues, suggestions and bugs regarding Entity Framework support in ADO.NET Data providers
Post Reply
laurensb
Posts: 13
Joined: Thu 06 Jun 2019 07:44

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

Post by laurensb » Wed 18 Dec 2019 13:15

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.

Shalex
Site Admin
Posts: 9103
Joined: Thu 14 Aug 2008 12:44

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

Post by Shalex » Thu 26 Dec 2019 13:37

Thank you for your report. We will investigate both issues and notify you about the result.

Shalex
Site Admin
Posts: 9103
Joined: Thu 14 Aug 2008 12:44

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

Post by Shalex » Sat 28 Dec 2019 12:20

// 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.

Shalex
Site Admin
Posts: 9103
Joined: Thu 14 Aug 2008 12:44

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

Post by Shalex » Tue 28 Jan 2020 20:19

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%'))

laurensb
Posts: 13
Joined: Thu 06 Jun 2019 07:44

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

Post by laurensb » Wed 29 Jan 2020 07:12

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.

Post Reply