linq2db / linq2db.EntityFrameworkCore

Bring power of Linq To DB to Entity Framework Core projects
MIT License
449 stars 39 forks source link

System.ArgumentException: Expression of type 'System.Byte' cannot be used for constructor parameter of type 'System.Int32' after 7.5.0->7.6.0 upgrade #368

Open aleksvujic opened 8 months ago

aleksvujic commented 8 months ago

We have a .NET 7 web application. We are using Microsoft.EntityFrameworkCore.Relational 7.0.13, Npgsql.EntityFrameworkCore.PostgreSQL 7.0.11 and linq2db.EntityFrameworkCore 7.6.0.

We use database-first approach and scaffold our database tables to C# models. Our scaffolded models look like this:

MyDbContext.cs

public partial class MyDbContext : DbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Project> Project { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Project>(entity =>
        {
            entity.HasKey(e => e.Id).HasName("project_pkey");

            entity.Property(e => e.Id).HasDefaultValueSql("nextval('project_id_seq'::regclass)");
        });

        OnModelCreatingPartial(modelBuilder);
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

Project.cs

[Table("project", Schema = "fit")]
[Index("Pkey", Name = "pkey_uq", IsUnique = true)]
public partial class Project
{
    [Key]
    [Column("id")]
    public int Id { get; set; }

    [Required]
    [Column("name")]
    [StringLength(255)]
    public string Name { get; set; }

    [Column("url")]
    [StringLength(255)]
    public string Url { get; set; }

    [Column("description")]
    public string Description { get; set; }

    [Column("pkey")]
    [StringLength(255)]
    public string Pkey { get; set; }
}

We noticed that after the upgrade of linq2db.EntityFrameworkCore 7.5.0 to 7.6.0, the following simple query stopped working:

public void Test()
{
    var allProjects = _fitDbContext.Project
        .ToLinqToDB()
        .ToList();
}

It throws the following exception:

System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
 ---> System.ArgumentException: Expression of type 'System.Byte' cannot be used for constructor parameter of type 'System.Int32' (Parameter 'arguments[1]')
   at System.Dynamic.Utils.ExpressionUtils.ValidateOneArgument(MethodBase method, ExpressionType nodeKind, Expression arguments, ParameterInfo pi, String methodParamName, String argumentParamName, Int32 index)
   at System.Dynamic.Utils.ExpressionUtils.ValidateArgumentTypes(MethodBase method, ExpressionType nodeKind, ReadOnlyCollection`1& arguments, String methodParamName)
   at System.Linq.Expressions.Expression.New(ConstructorInfo constructor, IEnumerable`1 arguments)
   at LinqToDB.DataProvider.PostgreSQL.NpgsqlProviderAdapter.GetInstance()
   at LinqToDB.DataProvider.PostgreSQL.PostgreSQLMappingSchema.PostgreSQL93MappingSchema..ctor()
   at LinqToDB.DataProvider.PostgreSQL.PostgreSQLDataProvider.GetMappingSchema(PostgreSQLVersion version)
   at LinqToDB.DataProvider.PostgreSQL.PostgreSQLDataProvider..ctor(String name, PostgreSQLVersion version)
   at LinqToDB.DataProvider.PostgreSQL.PostgreSQLDataProvider93..ctor()
   at System.RuntimeType.CreateInstanceOfT()
   --- End of inner exception stack trace ---
   at System.RuntimeType.CreateInstanceOfT()
   at System.Activator.CreateInstance[T]()
   at LinqToDB.Data.DataConnection.<>c__43`1.<CreateDataProvider>b__43_0()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at LinqToDB.DataProvider.PostgreSQL.PostgreSQLProviderDetector.GetDataProvider(ConnectionOptions options, Provider provider, PostgreSQLVersion version)
   at LinqToDB.DataProvider.PostgreSQL.PostgreSQLTools.GetDataProvider(PostgreSQLVersion version, String connectionString)
   at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.CreatePostgreSqlProvider(PostgreSQLVersion version, String connectionString)
   at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.CreateLinqToDBDataProvider(EFProviderInfo providerInfo, LinqToDBProviderInfo provInfo, EFConnectionInfo connectionInfo)
   at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.<>c__DisplayClass4_0.<GetDataProvider>b__0(ProviderKey k)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.GetDataProvider(DataOptions options, EFProviderInfo providerInfo, EFConnectionInfo connectionInfo)
   at LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.GetDataProvider(DataOptions options, EFProviderInfo info, EFConnectionInfo connectionInfo)
   at LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.CreateLinqToDBContext(DbContext context, IDbContextTransaction transaction)
   at LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.ToLinqToDB[T](IQueryable`1 query)
   at MyProject.Service.TestExecutionsService.Test() in E:\MyDevCheckouts\Develop\MyProject_branch3.5\MyProject.Service\TestExecutionsService.cs:line 59
   at MyProject.Service.TestExecutionsService.GetTestBisectedExecutions(String configuration, Int32 maxTransitions, String testName, String svnRevision) in E:\MyDevCheckouts\Develop\MyProject_branch3.5\MyProject.Service\TestExecutionsService.cs:line 66
   at MyProject.Web.Controllers.TestExecutions.TestExecutionsController.IndexAlternate(BisectExecutionsGuiModel model) in E:\MyDevCheckouts\Develop\MyProject_branch3.5\MyProject.Web\Controllers\TestExecutions\TestExecutionsController.cs:line 61
   at lambda_method151(Closure, Object, Object[])
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.SyncActionResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeNextActionFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at iSysCommon.Logging.RequestLoggingMiddleware.Invoke(HttpContext context) in E:\MyDevCheckouts\Develop\iSysCommonLibs_trunk\iSysCommon\Logging\RequestLoggingMiddleware.cs:line 44
   at iSysCommon.Logging.RequestLoggingMiddleware.Invoke(HttpContext context) in E:\MyDevCheckouts\Develop\iSysCommonLibs_trunk\iSysCommon\Logging\RequestLoggingMiddleware.cs:line 49
   at MyProject.Web.Middlewares.ResponseHeadersMiddleware.InvokeAsync(HttpContext context) in E:\MyDevCheckouts\Develop\MyProject_branch3.5\MyProject.Web\Middlewares\ResponseHeadersMiddleware.cs:line 51
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context)
   at DevExpress.AspNetCore.Internal.BinaryStorageMiddleware.Invoke(HttpContext httpContext)
   at DevExpress.AspNetCore.Internal.ResourceManagerMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)

If I remove .ToLinqToDB() call, it works normally.

Note: Keep in mind that I tried to make the example as simple as posible. Obviously, the real production query is much more complicated and actually requires linq2db functionality (PostgreSQL LEAD function).

MaceWindu commented 8 months ago

You need to add linq2db 5.3.2 dependency explicitly (temporary, till next release)

ryan-callahan-edo commented 8 months ago

I've been having the same issue on a new project for the past few days. Didn't put 2 + 2 together to pin it on the version. Adding the dependency worked like a charm.

aleksvujic commented 8 months ago

@MaceWindu Is this a bug or expected behavior? Is this documented somewhere?

MaceWindu commented 8 months ago

it's linq2db 5.3.1 regression, fixed in 5.3.2