首页 > 解决方案 > Linq2Db 异步插入 - 无法访问已处置的对象。ObjectDisposed_ObjectName_Name'

问题描述

我一直在做我自己的项目,我一直在使用 .Net Core 3.1 和 Linq2b ORM 工具。我有一个关于使用 async metot 插入数据的问题。我想插入一个日志数据。在 Linq2Db 中有一个称为InsertWithInt32IdentityAsync的方法。此方法返回一个错误,称为无法访问已处置的对象。对象名称:IServiceProvider

这是实现。

    [HttpPost("createpost")]
    [Authorize]
    public virtual async Task<JsonResult> CreatePost([FromForm] PostCreateApi model)
    {
        var serviceResponse = _postService.Create(model);

        if (serviceResponse.Warnings.Count > 0 || serviceResponse.Warnings.Any())
            return BadResponse(new ResultModel
            {
                Status = false,
                Message = serviceResponse.Warnings.First()
            });
        
        //Here returns an error
        await _logService.InsertLogAsync(Domain.Enumerations.LogLevel.Information, $"PostsController- Create Post Request", JsonConvert.SerializeObject(model));

        return OkResponse(new PostListDto
        {
            Id = serviceResponse.Data.Id,
            Text = serviceResponse.Data?.Text,
            ImageUrl = serviceResponse.Data.ImageUrl?.ToString(),
            CreatedByUserName = serviceResponse.Data?.CreatedByUserName,
            CreatedByUserPhoto = serviceResponse.Data?.CreatedByUserPhoto,
            CreatedDate = serviceResponse.Data.CreatedDate,
            VideoUrl = serviceResponse.Data?.VideoUrl,
            PostType = serviceResponse.Data?.PostType,
            Comments = null
        });
    }

这是InsertLogAsync方法。

 public virtual async Task<Log> InsertLogAsync(LogLevel logLevel, string shortMessage, string fullMessage = "", AppUser appUser = null)
    {
        var log = new Log
        {
            LogLevel = logLevel,
            ShortMessage = shortMessage,
            FullMessage = fullMessage,
            IpAddress = _webHelper.GetCurrentIpAddress(),
            CustomerId = appUser?.Id,
            PageUrl = _webHelper.GetThisPageUrl(true),
            ReferrerUrl = _webHelper.GetUrlReferrer(),
            CreatedDate = DateTime.UtcNow
        };

        await _logRepository.InsertAsync(log);

        return log;
    }

这是 BaseDataProvider InsertEntityAsync方法。

  public virtual async Task<TEntity> InsertEntityAsync<TEntity>(TEntity entity) where TEntity : 
  BaseEntity
    {
        using var dataContext = CreateDataConnection();
        entity.Id = await dataContext.InsertWithInt32IdentityAsync(entity);
        return entity;
    }

这是StackTrace

在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ThrowHelper.ThrowObjectDisposedException() 在 Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) 在 Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) 在 FluentMigrator。 C:\Projects\DevPlatform\DevPlatform.Data\Migrations\MigrationManager.cs:line 中 DevPlatform.Data.Migrations.MigrationManager.CreateNullMigrationContext() 的 Infrastructure.MigrationContext..ctor(IQuerySchema querySchema, IServiceProvider serviceProvider, Object context, String connection) 165 at DevPlatform.Data.Migrations.MigrationManager.GetCreateTableExpression(Type type) in C:\Projects\DevPlatform\DevPlatform.Data\Migrations\MigrationManager.cs:DevPlatform.Data.Mapping 的第 240 行。FluentMigratorMetadataReader.<>c__DisplayClass2_01.<GetAttribute>b__1(Type entityType) in C:\Projects\DevPlatform\DevPlatform.Data\Mapping\FluentMigratorMetadataReader.cs:line 42 at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func 2 valueFactory) at DevPlatform.Data.Mapping.FluentMigratorMetadataReader.<>c__DisplayClass2_01.b__0(ValueTuple 2 t) in C:\Projects\DevPlatform\DevPlatform.Data\Mapping\FluentMigratorMetadataReader.cs:line 42 at System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func 2 valueFactory) at DevPlatform.Data.Mapping.FluentMigratorMetadataReader.GetAttribute[T](Type type, MemberInfo memberInfo) in C:\Projects\DevPlatform\DevPlatform.Data\Mapping\FluentMigratorMetadataReader.cs:line 40 at DevPlatform.Data.Mapping.FluentMigratorMetadataReader.GetAttributes[T](Type type, Type attributeType, MemberInfo memberInfo) in C:\Projects\DevPlatform\DevPlatform.Data\Mapping\FluentMigratorMetadataReader.cs:line 76 at DevPlatform.Data.Mapping.FluentMigratorMetadataReader.GetAttributes[T](Type type, Boolean inherit) in C:\Projects\DevPlatform\DevPlatform.Data\Mapping\FluentMigratorMetadataReader.cs:line 97 at LinqToDB.Mapping.MappingSchema.<>c__DisplayClass51_01.b__0(IMetadataReader mr) at System.Linq.Enumerable.d__181 3.MoveNext() at System.Collections.Generic.LargeArrayBuilder1.AddRange(IEnumerable 1 items) at System.Collections.Generic.EnumerableHelpers.ToArray[T](IEnumerable1 source) at LinqToDB.Mapping.MappingSchema .GetAttributes[T](类型类型,布尔继承)在 LinqToDB.Mapping.MappingSchema.GetAttributes[T](类型类型,Func 2 configGetter, Boolean inherit, Boolean exactForConfiguration) at LinqToDB.Mapping.MappingSchema.GetAttribute[T](Type type, Func2 configGetter,布尔继承)在 LinqToDB.Mapping.EntityDescriptor.Init() 在 LinqToDB.Mapping.EntityDescriptor ..ctor(MappingSchema mappingSchema, Type type) 在 LinqToDB.Mapping.MappingSchema.<>c.b__92_0(ICacheEntry o, <>f__AnonymousType131 2 key, MappingSchema context) at LinqToDB.Common.Internal.Cache.CacheExtensions.GetOrCreate[TItem,TKey,TContext](IMemoryCache cache, TKey key, TContext context, Func4 factory) 在 LinqToDB.Mapping.MappingSchema.GetEntityDescriptor(Type type) 在 LinqToDB.Linq.QueryRunner .GetType[T](T obj, IDataContext db) 在 LinqToDB.Linq.QueryRunner.InsertWithIdentity`1.d__2.MoveNext()

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

标签: c#.netasync-awaitasp.net5linq2db

解决方案


该问题已通过编辑CreateTableExpressionBuilder并调用 _migrationContext 而不是调用 CreateNullMigrationContext 函数来解决。

而不是下面的代码块;

    public virtual CreateTableExpression GetCreateTableExpression(Type type)
    {
        var expression = new CreateTableExpression { TableName = NameCompatibilityManager.GetTableName(type) };
        var builder = new CreateTableExpressionBuilder(expression, CreateNullMigrationContext());

        RetrieveTableExpressions(type, builder);

        return builder.Expression;
    }

我已针对此问题更改了CreateTableExpressionBuilder 。

 public virtual CreateTableExpression GetCreateTableExpression(Type type)
    {
        var expression = new CreateTableExpression { TableName = NameCompatibilityManager.GetTableName(type) };
        var builder = new CreateTableExpressionBuilder(expression, _migrationContext);

        RetrieveTableExpressions(type, builder);

        return builder.Expression;
    }

正如我所提到的,CreateNullMigrationContext函数返回一个错误。

 protected IMigrationContext CreateNullMigrationContext()
    {
        return new MigrationContext(new NullIfDatabaseProcessor(), 
          _migrationContext.ServiceProvider, null, null);
    }

非常感谢。@StriplingWarrior、@Paulo Morgado 和 @Svyatoslav Danyliv


推荐阅读