最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Linq2Db update MissingMethodException - Stack Overflow

programmeradmin4浏览0评论

This is my command code

using CBRRS.SBL.Application.Common;
using CBRRS.SBL.Application.Common.Interfaces;
using CBRRS.SBL.Application.Common.Models;
using CBRRS.SBL.Domain.Common;
using CBRRS.SBL.Domain.ModuleFunctionStatus;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using LinqToDB; // Required for bulk update
using LinqToDB.EntityFrameworkCore;
using CBRRS.SBL.Domain.Entities.CARR.OFFBS; // Required for Linq2DB with EF Core

namespace CBRRS.SBL.Application.CARR.OFFBS.OffBsSummary.Commands;

public class CarrOffBsSummaryRiskWeightUpdateCommand : IRequest<Result>
{
    public List<CarrOffBsCustomerResponse> Customers { get; set; }
}

public class CarrOffBsSummaryRiskWeightUpdateCommandHandler : IRequestHandler<CarrOffBsSummaryRiskWeightUpdateCommand, Result>
{
    private readonly IApplicationDbContext _context;
    private readonly ILogger<CarrOffBsSummaryRiskWeightUpdateCommandHandler>_logger;
    private readonly IModuleFunctionStatusService _moduleFunctionStatusService;

    public CarrOffBsSummaryRiskWeightUpdateCommandHandler(IApplicationDbContext context, ILogger<CarrOffBsSummaryRiskWeightUpdateCommandHandler> logger, IModuleFunctionStatusService moduleFunctionStatusService)
    {
        _context = context;
        _logger = logger;
        _moduleFunctionStatusService = moduleFunctionStatusService;
    }

    public async Task<Result> Handle(CarrOffBsSummaryRiskWeightUpdateCommand request, CancellationToken cancellationToken)
    {
        try
        {


            _logger.LogInformation("========== Start CarrOffBsSummaryRiskWeightUpdateCommandHandler ==========");

            var customerIds = request.Customers.Select(c => c.CustomerId).ToList();

            //var customers = await _context.CarrOffBsRiskRating
            //    .Where(c => customerId.Contains(c.CustomerId))
            //    .ToListAsync(cancellationToken);

            //_logger.LogInformation("Fetched {FetchedCount} Risk Rating records from the database.", customers.Count);

            //foreach (var customer in customers)
            //{
            //    var updateCustomer = request.Customers.FirstOrDefault(c => c.CustomerId == customer.CustomerId);
            //    if (updateCustomer != null)
            //    {
            //        customer.RiskRating = updateCustomer.RiskRating;
            //        customer.Status = AuthEnums.AuthorizedStatus.Pending;
            //    }
            //}

            // Perform a bulk update directly in the database
            int count = await _context.CarrOffBsRiskRating
                .Where(c => customerIds.Contains(c.CustomerId))
                .AsQueryable()
                .ToLinqToDB()
                .UpdateAsync(c => new CarrOffBsRiskRating
                {
                    RiskRating = request.Customers.FirstOrDefault(rc => rc.CustomerId == c.CustomerId).RiskRating,
                    Status = AuthEnums.AuthorizedStatus.Pending
                }, token: cancellationToken);

            _logger.LogInformation("Updating {UpdateCount} Risk Rating records in the database. Record Count : ", count);
            //_context.CarrOffBsRiskRating.UpdateRange();
            // Use BulkUpdateAsync to efficiently update all records in one call

            //await _context.BulkUpdateAsync(customers, cancellationToken: cancellationToken);

            //await _context.SaveChangesAsync(cancellationToken);
            _logger.LogInformation("Database changes saved successfully.");

            _logger.LogInformation("========== End CarrOffBsSummaryRiskWeightUpdateCommandHandler ==========");

            await _moduleFunctionStatusService.UpdateAsync(ModuleNames.CarrOffBsSummaryMaintenance, Status.Active, cancellationToken);

            return Result.Success();

        }
        catch(Exception ex) 
        {
            throw;
        }
    }
}

I Change this code because the data that need to update has 15000 or more rows so th ef core one is slow. I use Linq2Db to do the process but now this error comes

System.MissingMethodException HResult=0x80131513 Message=Method not found: 'Void LinqToDB.Mapping.MappingSchema.SetConvertExpression(System.Type, System.Type, System.Linq.Expressions.LambdaExpression, Boolean)'.
Source=linq2db.EntityFrameworkCore StackTrace: at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.<>c__DisplayClass14_0.g__MapEFCoreType|1(Type modelType) at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.DefineConvertors(MappingSchema mappingSchema, IModel model, IValueConverterSelector convertorSelector, DataOptions dataOptions) at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.CreateMappingSchema(IModel model, IMetadataReader metadataReader, IValueConverterSelector convertorSelector, DataOptions dataOptions) at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.<>c__DisplayClass17_0.b__0(ICacheEntry e) at Microsoft.Extensions.Caching.Memory.CacheExtensions.GetOrCreate[TItem](IMemoryCache cache, Object key, Func2 factory) at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.GetMappingSchema(IModel model, IMetadataReader metadataReader, IValueConverterSelector convertorSelector, DataOptions dataOptions) at LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.GetMappingSchema(IModel model, IInfrastructure1 accessor, DataOptions dataOptions) at LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.CreateLinqToDBContext(DbContext context, IDbContextTransaction transaction) at LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.ToLinqToDB[T](IQueryable`1 query) at CBRRS.SBL.Application.CARR.OFFBS.OffBsSummary.Commands.CarrOffBsSummaryRiskWeightUpdateCommandHandler.d__4.MoveNext() in D:\Azure Development\DMSSWE.CBRRS.SBL.NEW\DMSSWE.CBRRS.SBL\CBRRS.SBL.Application\CARR\OFFBS\OffBsSummary\Commands\CarrOffBsSummaryRiskWeightUpdateCommand.cs:line 60

This exception was originally thrown at this call stack: LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.DefineConvertors(LinqToDB.Mapping.MappingSchema, Microsoft.EntityFrameworkCore.Metadata.IModel, Microsoft.EntityFrameworkCore.Storage.ValueConversion.IValueConverterSelector, LinqToDB.DataOptions) LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.CreateMappingSchema(Microsoft.EntityFrameworkCore.Metadata.IModel, LinqToDB.Metadata.IMetadataReader, Microsoft.EntityFrameworkCore.Storage.ValueConversion.IValueConverterSelector, LinqToDB.DataOptions) LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.GetMappingSchema.AnonymousMethod__0(Microsoft.Extensions.Caching.Memory.ICacheEntry) Microsoft.Extensions.Caching.Memory.CacheExtensions.GetOrCreate(Microsoft.Extensions.Caching.Memory.IMemoryCache, object, System.Func<Microsoft.Extensions.Caching.Memory.ICacheEntry, TItem>) LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.GetMappingSchema(Microsoft.EntityFrameworkCore.Metadata.IModel, LinqToDB.Metadata.IMetadataReader, Microsoft.EntityFrameworkCore.Storage.ValueConversion.IValueConverterSelector, LinqToDB.DataOptions) LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.GetMappingSchema(Microsoft.EntityFrameworkCore.Metadata.IModel, Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>, LinqToDB.DataOptions) LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.CreateLinqToDBContext(Microsoft.EntityFrameworkCore.DbContext, Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction) LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.ToLinqToDB(System.Linq.IQueryable) CBRRS.SBL.Application.CARR.OFFBS.OffBsSummary.Commands.CarrOffBsSummaryRiskWeightUpdateCommandHandler.Handle(CBRRS.SBL.Application.CARR.OFFBS.OffBsSummary.Commands.CarrOffBsSummaryRiskWeightUpdateCommand, System.Threading.CancellationToken) in CarrOffBsSummaryRiskWeightUpdateCommand.cs

Why this error come, and how do I fix this error

Package versions Microsoft.EntityFrameworkCore - 8.0.7 linq2db - 6.0.0-preview.1 linq2db.EntityFrameworkCore - 8.0.0

This is my command code

using CBRRS.SBL.Application.Common;
using CBRRS.SBL.Application.Common.Interfaces;
using CBRRS.SBL.Application.Common.Models;
using CBRRS.SBL.Domain.Common;
using CBRRS.SBL.Domain.ModuleFunctionStatus;
using MediatR;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using LinqToDB; // Required for bulk update
using LinqToDB.EntityFrameworkCore;
using CBRRS.SBL.Domain.Entities.CARR.OFFBS; // Required for Linq2DB with EF Core

namespace CBRRS.SBL.Application.CARR.OFFBS.OffBsSummary.Commands;

public class CarrOffBsSummaryRiskWeightUpdateCommand : IRequest<Result>
{
    public List<CarrOffBsCustomerResponse> Customers { get; set; }
}

public class CarrOffBsSummaryRiskWeightUpdateCommandHandler : IRequestHandler<CarrOffBsSummaryRiskWeightUpdateCommand, Result>
{
    private readonly IApplicationDbContext _context;
    private readonly ILogger<CarrOffBsSummaryRiskWeightUpdateCommandHandler>_logger;
    private readonly IModuleFunctionStatusService _moduleFunctionStatusService;

    public CarrOffBsSummaryRiskWeightUpdateCommandHandler(IApplicationDbContext context, ILogger<CarrOffBsSummaryRiskWeightUpdateCommandHandler> logger, IModuleFunctionStatusService moduleFunctionStatusService)
    {
        _context = context;
        _logger = logger;
        _moduleFunctionStatusService = moduleFunctionStatusService;
    }

    public async Task<Result> Handle(CarrOffBsSummaryRiskWeightUpdateCommand request, CancellationToken cancellationToken)
    {
        try
        {


            _logger.LogInformation("========== Start CarrOffBsSummaryRiskWeightUpdateCommandHandler ==========");

            var customerIds = request.Customers.Select(c => c.CustomerId).ToList();

            //var customers = await _context.CarrOffBsRiskRating
            //    .Where(c => customerId.Contains(c.CustomerId))
            //    .ToListAsync(cancellationToken);

            //_logger.LogInformation("Fetched {FetchedCount} Risk Rating records from the database.", customers.Count);

            //foreach (var customer in customers)
            //{
            //    var updateCustomer = request.Customers.FirstOrDefault(c => c.CustomerId == customer.CustomerId);
            //    if (updateCustomer != null)
            //    {
            //        customer.RiskRating = updateCustomer.RiskRating;
            //        customer.Status = AuthEnums.AuthorizedStatus.Pending;
            //    }
            //}

            // Perform a bulk update directly in the database
            int count = await _context.CarrOffBsRiskRating
                .Where(c => customerIds.Contains(c.CustomerId))
                .AsQueryable()
                .ToLinqToDB()
                .UpdateAsync(c => new CarrOffBsRiskRating
                {
                    RiskRating = request.Customers.FirstOrDefault(rc => rc.CustomerId == c.CustomerId).RiskRating,
                    Status = AuthEnums.AuthorizedStatus.Pending
                }, token: cancellationToken);

            _logger.LogInformation("Updating {UpdateCount} Risk Rating records in the database. Record Count : ", count);
            //_context.CarrOffBsRiskRating.UpdateRange();
            // Use BulkUpdateAsync to efficiently update all records in one call

            //await _context.BulkUpdateAsync(customers, cancellationToken: cancellationToken);

            //await _context.SaveChangesAsync(cancellationToken);
            _logger.LogInformation("Database changes saved successfully.");

            _logger.LogInformation("========== End CarrOffBsSummaryRiskWeightUpdateCommandHandler ==========");

            await _moduleFunctionStatusService.UpdateAsync(ModuleNames.CarrOffBsSummaryMaintenance, Status.Active, cancellationToken);

            return Result.Success();

        }
        catch(Exception ex) 
        {
            throw;
        }
    }
}

I Change this code because the data that need to update has 15000 or more rows so th ef core one is slow. I use Linq2Db to do the process but now this error comes

System.MissingMethodException HResult=0x80131513 Message=Method not found: 'Void LinqToDB.Mapping.MappingSchema.SetConvertExpression(System.Type, System.Type, System.Linq.Expressions.LambdaExpression, Boolean)'.
Source=linq2db.EntityFrameworkCore StackTrace: at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.<>c__DisplayClass14_0.g__MapEFCoreType|1(Type modelType) at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.DefineConvertors(MappingSchema mappingSchema, IModel model, IValueConverterSelector convertorSelector, DataOptions dataOptions) at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.CreateMappingSchema(IModel model, IMetadataReader metadataReader, IValueConverterSelector convertorSelector, DataOptions dataOptions) at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.<>c__DisplayClass17_0.b__0(ICacheEntry e) at Microsoft.Extensions.Caching.Memory.CacheExtensions.GetOrCreate[TItem](IMemoryCache cache, Object key, Func2 factory) at LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.GetMappingSchema(IModel model, IMetadataReader metadataReader, IValueConverterSelector convertorSelector, DataOptions dataOptions) at LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.GetMappingSchema(IModel model, IInfrastructure1 accessor, DataOptions dataOptions) at LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.CreateLinqToDBContext(DbContext context, IDbContextTransaction transaction) at LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.ToLinqToDB[T](IQueryable`1 query) at CBRRS.SBL.Application.CARR.OFFBS.OffBsSummary.Commands.CarrOffBsSummaryRiskWeightUpdateCommandHandler.d__4.MoveNext() in D:\Azure Development\DMSSWE.CBRRS.SBL.NEW\DMSSWE.CBRRS.SBL\CBRRS.SBL.Application\CARR\OFFBS\OffBsSummary\Commands\CarrOffBsSummaryRiskWeightUpdateCommand.cs:line 60

This exception was originally thrown at this call stack: LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.DefineConvertors(LinqToDB.Mapping.MappingSchema, Microsoft.EntityFrameworkCore.Metadata.IModel, Microsoft.EntityFrameworkCore.Storage.ValueConversion.IValueConverterSelector, LinqToDB.DataOptions) LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.CreateMappingSchema(Microsoft.EntityFrameworkCore.Metadata.IModel, LinqToDB.Metadata.IMetadataReader, Microsoft.EntityFrameworkCore.Storage.ValueConversion.IValueConverterSelector, LinqToDB.DataOptions) LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.GetMappingSchema.AnonymousMethod__0(Microsoft.Extensions.Caching.Memory.ICacheEntry) Microsoft.Extensions.Caching.Memory.CacheExtensions.GetOrCreate(Microsoft.Extensions.Caching.Memory.IMemoryCache, object, System.Func<Microsoft.Extensions.Caching.Memory.ICacheEntry, TItem>) LinqToDB.EntityFrameworkCore.LinqToDBForEFToolsImplDefault.GetMappingSchema(Microsoft.EntityFrameworkCore.Metadata.IModel, LinqToDB.Metadata.IMetadataReader, Microsoft.EntityFrameworkCore.Storage.ValueConversion.IValueConverterSelector, LinqToDB.DataOptions) LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.GetMappingSchema(Microsoft.EntityFrameworkCore.Metadata.IModel, Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>, LinqToDB.DataOptions) LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.CreateLinqToDBContext(Microsoft.EntityFrameworkCore.DbContext, Microsoft.EntityFrameworkCore.Storage.IDbContextTransaction) LinqToDB.EntityFrameworkCore.LinqToDBForEFTools.ToLinqToDB(System.Linq.IQueryable) CBRRS.SBL.Application.CARR.OFFBS.OffBsSummary.Commands.CarrOffBsSummaryRiskWeightUpdateCommandHandler.Handle(CBRRS.SBL.Application.CARR.OFFBS.OffBsSummary.Commands.CarrOffBsSummaryRiskWeightUpdateCommand, System.Threading.CancellationToken) in CarrOffBsSummaryRiskWeightUpdateCommand.cs

Why this error come, and how do I fix this error

Package versions Microsoft.EntityFrameworkCore - 8.0.7 linq2db - 6.0.0-preview.1 linq2db.EntityFrameworkCore - 8.0.0

Share Improve this question edited Mar 26 at 10:14 Gert Arnold 109k36 gold badges214 silver badges313 bronze badges asked Mar 26 at 8:08 Vinuka OsuraVinuka Osura 1291 silver badge13 bronze badges 7
  • There should be way to do this using EF's ExecuteUpdate(). It would help to see the classes. – Gert Arnold Commented Mar 26 at 8:18
  • Are you suggesting EFCore.BulkExtensions? Is this free and ok to use – Vinuka Osura Commented Mar 26 at 9:29
  • No, EF's own ExecuteUpdate. – Gert Arnold Commented Mar 26 at 9:30
  • I think you can use it, see the answer, although it's still interesting why the LinqToDB exception occurs. Hopefully, Svyatoslav Danyliv chimes in. – Gert Arnold Commented Mar 26 at 9:49
  • @VinukaOsura, there is issue with packages, can you work without linq2db preview versions? If not, we plan to create preview 4 packages later today and you will be able to use preview version with EF Core 8. – Svyatoslav Danyliv Commented Mar 26 at 10:27
 |  Show 2 more comments

2 Answers 2

Reset to default 2

Problem that you have used linq2db - 6.0.0-preview.1, which is not suitable with linq2db.EntityFrameworkCore - 8.0.0

To solve issue, you have to downgrade linq2db to version 5.4.1, or install both preview packages:

linq2db --version 6.0.0-preview.4
linq2db.EntityFrameworkCore --version 8.2.0-preview.4

If I inferred the class model correctly, you could use EF's own ExecuteUpdate:

await context.CarrOffBsRiskRatings.Select(r => new
{ 
    Rating = r,
    CustomerRating = r.Customer.RiskRating
}).ExecuteUpdateAsync(spc => spc
    .SetProperty(x => x.Rating.RiskRating, x => x.CustomerRating)
    .SetProperty(x => x.Rating.Status, AuthorizedStatus.Pending),
    cancellationToken);
发布评论

评论列表(0)

  1. 暂无评论