Skip to content

Npgsql InvalidCastException with Guid Value in Select in Entity Framework Query #3507

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

Closed
espentveit opened this issue Mar 21, 2025 · 3 comments

Comments

@espentveit
Copy link

espentveit commented Mar 21, 2025

Passing a Guid.Empty into a view model property in a projection causes a System.InvalidCastException ("Reading as 'System.Guid' is not supported for fields having DataTypeName 'text'")

Steps to Reproduce

public class SoftwareVendor
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}
public class SoftwareVendorDatatableVm
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public Guid VariableKey { get; set; }
    public Guid VariableId { get; set; }
}

Running a query using this (simplified):

var result = 
    context
    .SoftwareVendors
        .Select(x => new SoftwareVendorDatatableVm
        {
            Id = x.Id,
            Name = x.Name,
            VariableKey = Guid.Empty,
            VariableId = Guid.Empty
        })
        .ToList();

Gets converted into this:

SELECT s."Id", s."Name", '00000000-0000-0000-0000-000000000000' AS "VariableKey", '00000000-0000-0000-0000-000000000000' AS "VariableId"
FROM "SoftwareVendor"

The result:
System.InvalidCastException: Reading as 'System.Guid' is not supported for fields having DataTypeName 'text'
at Npgsql.Internal.AdoSerializerHelpers.g__ThrowReadingNotSupported|0_0(Type type, String displayName, Exception inner)
at Npgsql.Internal.AdoSerializerHelpers.GetTypeInfoForReading(Type type, PostgresType postgresType, PgSerializerOptions options)
at Npgsql.BackendMessages.FieldDescription.g__GetInfoSlow|50_0(Type type, ColumnInfo& lastColumnInfo)
at Npgsql.BackendMessages.FieldDescription.GetInfo(Type type, ColumnInfo& lastColumnInfo)
at Npgsql.NpgsqlDataReader.g__Slow|133_0(ColumnInfo& info, PgConverter& converter, Size& bufferRequirement, Boolean& asObject, <>c__DisplayClass133_0&)
at Npgsql.NpgsqlDataReader.GetFieldValueCore[T](Int32 ordinal)
at lambda_method7389(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)

The generated query should probably have looked like this:

SELECT s."Id", s."Name", '00000000-0000-0000-0000-000000000000'::uuid AS "VariableKey", '00000000-0000-0000-0000-000000000000'::uuid AS "VariableId"
FROM "SoftwareVendor"
@vonzshik vonzshik transferred this issue from npgsql/npgsql Mar 21, 2025
@espentveit
Copy link
Author

espentveit commented Mar 21, 2025

A more standalone example:

mkdir guid-test
cd guid-test
dotnet new console
# Replace Program.cs with source code below
dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet ef migrations add Initial 
dotnet ef database update
dotnet run
using Microsoft.EntityFrameworkCore;

var context = new BloggingContext();
context.Blogs.Add(new Blog {
    BlogId = Guid.NewGuid(),
    Url = "/some/url"
});
context.SaveChanges();

var query = context.Blogs.Select(a => new BlogVm {
    BlogId = a.BlogId,
    Url = a.Url,
    SomeViewModelReference = Guid.Empty
}).ToList();

public class BlogVm 
{
    public Guid BlogId { get; set; }
    public string Url { get; set; }
    public Guid SomeViewModelReference { get; set; }
}

public class Blog
{
    public Guid BlogId { get; set; }
    public string Url { get; set; }
}

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        => optionsBuilder.UseNpgsql("Server=localhost;port=5432;Database=blog");
}
Unhandled exception. System.InvalidCastException: Reading as 'System.Guid' is not supported for fields having DataTypeName 'text'
   at Npgsql.Internal.AdoSerializerHelpers.<GetTypeInfoForReading>g__ThrowReadingNotSupported|0_0(Type type, PgSerializerOptions options, PgTypeId pgTypeId, Exception inner)
   at Npgsql.Internal.AdoSerializerHelpers.GetTypeInfoForReading(Type type, PgTypeId pgTypeId, PgSerializerOptions options)
   at Npgsql.BackendMessages.FieldDescription.<GetInfoCore>g__GetInfoSlow|51_0(Type type, ColumnInfo& lastColumnInfo)
   at Npgsql.BackendMessages.FieldDescription.GetInfoCore(Type type, ColumnInfo& lastColumnInfo)
   at Npgsql.BackendMessages.FieldDescription.GetInfo(Type type, ColumnInfo& lastColumnInfo)
   at Npgsql.NpgsqlDataReader.<GetInfo>g__Slow|133_0(ColumnInfo& info, PgConverter& converter, Size& bufferRequirement, Boolean& asObject, <>c__DisplayClass133_0&)
   at Npgsql.NpgsqlDataReader.GetFieldValueCore[T](Int32 ordinal)
   at Npgsql.NpgsqlDataReader.GetGuid(Int32 ordinal)
   at lambda_method33(Closure, QueryContext, DbDataReader, ResultContext, SingleQueryResultCoordinator)
   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 Program.<Main>$(String[] args)

@roji
Copy link
Member

roji commented Mar 21, 2025

@espentveit thanks for filing this and including a minimal repro - I can indeed see the error happening. This isn't PG-specific, so I've opened dotnet/efcore#35826 on the EF side and will close the issue here.

In the meantime, you can workaround the issue by not populating the Guid directly, but by adding another step outside the query to do that.

@roji roji closed this as completed Mar 21, 2025
@espentveit
Copy link
Author

@roji Sounds good. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants