Skip to content
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

Queryable projection faults when assigning default values #27659

Closed
sommmen opened this issue Mar 17, 2022 · 2 comments
Closed

Queryable projection faults when assigning default values #27659

sommmen opened this issue Mar 17, 2022 · 2 comments

Comments

@sommmen
Copy link

sommmen commented Mar 17, 2022

EF Core version: 6.0.3
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: (e.g. .NET 5.0) .NET 6.0.3
Operating system: Windows
IDE: (e.g. Visual Studio 2019 16.3) Vs2022 17.1.1

Hello,

I have this (rather simple) entity:

public class HarvestLLTimeSheet
{

    public Guid Id { get; set; }

    public DateTimeOffset Day { get; set; }

    public double Hours { get; set; }

    [StringLength(64)]
    public string? Task { get; set; }

    [StringLength(256)]
    public string? Note { get; set; }

    [StringLength(32)]
    public string? User { get; set; }
}

I'm running some .Where() filters, then a group by and then a projection for the groupby. Here's some sample code to demonstarate:

var qTestSelectOnly = qHarvestLLTimeSheets
    .Where(c => c.Day <= DateTimeOffset.Now && c.Day >= DateTimeOffset.Now.AddMonths(-1))
    .Select(x => new HarvestLLTimeSheet
    {
        //Id = default,
        //Day = default,
        Hours = x.Hours,
        Note = x.Note,
        Task = x.Task,
        User = x.User
    });

var qTestGroupBy = qHarvestLLTimeSheets
    .Where(c => c.Day <= DateTimeOffset.Now && c.Day >= DateTimeOffset.Now.AddMonths(-1))
    .GroupBy(c => c.User)
    .Select(c => new HarvestLLTimeSheet
    {
        Hours = c.Sum(x => x.Hours),
        Note = c.Max(x => x.Note),
        Task = c.Max(x => x.Task),
        User = c.Max(x => x.User)
    });

var qTestGroupByWithDefault = qHarvestLLTimeSheets
    .Where(c => c.Day <= DateTimeOffset.Now && c.Day >= DateTimeOffset.Now.AddMonths(-1))
    .GroupBy(c => c.User)
    .Select(c => new HarvestLLTimeSheet
    {
        Id = default,
        Day = default,
        Hours = c.Sum(x => x.Hours),
        Note = c.Max(x => x.Note),
        Task = c.Max(x => x.Task),
        User = c.Max(x => x.User)
    });

var selectOnly = qTestSelectOnly.ToList();
var groupBy = qTestGroupBy.ToList();
var groupByWithDefault = qTestGroupByWithDefault.ToList();

selectOnly and groupBy works groupByWithDefault does not:

image

System.InvalidOperationException
  HResult=0x80131509
  Message=An error occurred while reading a database value. The expected type was 'System.Nullable`1[System.Guid]' but the actual value was of type 'System.String'.
  Source=Microsoft.EntityFrameworkCore.Relational
  StackTrace:
   at Microsoft.EntityFrameworkCore.Query.RelationalShapedQueryCompilingExpressionVisitor.ShaperProcessingExpressionVisitor.ThrowReadValueException[TValue](Exception exception, Object value, Type expectedType, IPropertyBase property)
   at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.Enumerator.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at [REDACTED].WebApi.Controllers.HarvestLLTimeSheetController.<Get>d__2.MoveNext() in [REDACTED]\HarvestLLTimeSheetController.cs:line 96

  This exception was originally thrown at this call stack:
    Microsoft.Data.SqlClient.SqlBuffer.Guid.get()
    Microsoft.Data.SqlClient.SqlDataReader.GetGuid(int)

Inner Exception 1:
InvalidCastException: Unable to cast object of type 'System.String' to type 'System.Guid'.

The same error happens here:

var qTestSelectOnlyWithDefault = qHarvestLLTimeSheets
    .Select(x => new HarvestLLTimeSheet
    {
        Id = default,
        Day = default,
        Hours =  x.Hours,
        Note =  x.Note,
        Task =  x.Task,
        User =  x.User
    });

var selectOnlyWithDefault = qTestSelectOnlyWithDefault.ToList();

And here:

var qTestSelectOnlyWithDefault = qHarvestLLTimeSheets
    //.Where(c => c.Day <= DateTimeOffset.Now && c.Day >= DateTimeOffset.Now.AddMonths(-1))
    .Select(x => new HarvestLLTimeSheet
    {
        //Id = default,
        Day = default,
        Hours =  x.Hours,
        Note =  x.Note,
        Task =  x.Task,
        User =  x.User
    });

var selectOnlyWithDefault = qTestSelectOnlyWithDefault.ToList();

Is this intentional because this seems like a bug - hence this report.

Why i'm using default here? Well for both clarity and intellisense.

@smitpatel
Copy link
Member

Duplicate of #24075

Issue is that the literal representation of default of Guid in SqlServer gets sent back as string so when we try to read Guid it throws above exception.

@sommmen
Copy link
Author

sommmen commented Mar 18, 2022

Duplicate of #24075

Issue is that the literal representation of default of Guid in SqlServer gets sent back as string so when we try to read Guid it throws above exception.

I see - sorry for the dupe!

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants