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

Add built-in value converters for IPAddress or PhysicalAddress #18662

Closed
tfadler opened this issue Oct 30, 2019 · 8 comments · Fixed by #20679
Closed

Add built-in value converters for IPAddress or PhysicalAddress #18662

tfadler opened this issue Oct 30, 2019 · 8 comments · Fixed by #20679
Assignees
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-enhancement
Milestone

Comments

@tfadler
Copy link

tfadler commented Oct 30, 2019

If I have either an IPAddress or PhysicalAddress property on an entity and set it up for UseInMemoryDatabase() there will be exceptions when the database is created.

Note that these data types are acceptable in my real database (postgresql)

Thought it may be related to this: #11074

Steps to reproduce

Here is a sample application displaying the problem

namespace EfTest
{
	public class Program
	{
		public static void Main(string[] args)
		{
			using (var db = new MyContext())
			{
				// Recreate database
				db.Database.EnsureDeleted();
				db.Database.EnsureCreated();

				// Seed database

				db.SaveChanges();
			}

			using (var db = new MyContext())
			{
				// Run queries
			}

			Console.WriteLine("Program finished.");
		}
	}

	public class MyContext : DbContext
	{
		// Declare DBSets
		public DbSet<NetworkStuff> NetworkStuffs { get; set; }

		protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
		{
			// Select 1 provider
			optionsBuilder
				.UseInMemoryDatabase(databaseName: "modelname");
		}

		protected override void OnModelCreating(ModelBuilder modelBuilder)
		{
		}
	}

	public class NetworkStuff
	{
		public int Id { get; set; }

		public IPAddress IpAddress1 { get; set; }
		public PhysicalAddress Mac1 { get; set; }
	}
}

Exception for IPAddress:

System.InvalidOperationException
HResult=0x80131509
Message=No suitable constructor found for entity type 'IPAddress'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'newAddress' in 'IPAddress(long newAddress)'; cannot bind 'address', 'scopeid' in 'IPAddress(byte[] address, long scopeid)'; cannot bind 'address', 'scopeid' in 'IPAddress(ReadOnlySpan address, long scopeid)'; cannot bind 'numbers', 'scopeid' in 'IPAddress(ReadOnlySpan numbers, uint scopeid)'; cannot bind 'numbers', 'scopeid' in 'IPAddress(ushort[] numbers, uint scopeid)'; cannot bind 'address' in 'IPAddress(byte[] address)'; cannot bind 'address' in 'IPAddress(ReadOnlySpan address)'.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.Metadata.Conventions.ConstructorBindingConvention.ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext1 context) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IConventionModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IConventionModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel() at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel() at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder) at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.<GetModel>b__1() at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) at System.Lazy1.CreateValue()
at System.Lazy1.get_Value() at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder) at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel() at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model() at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_3(IServiceProvider p) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider() at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance() at Microsoft.EntityFrameworkCore.Infrastructure.Internal.InfrastructureExtensions.GetService[TService](IInfrastructure1 accessor)
at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.get_Dependencies()
at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.EnsureDeleted()
at EfTest.Program.Main(String[] args) in C:\Users\name\source\repos\EfTest\EfTest\Program.cs:line 16

Exception for PhysicalAddress (have to comment out IPAddress property)

System.InvalidOperationException
HResult=0x80131509
Message=No suitable constructor found for entity type 'PhysicalAddress'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'address' in 'PhysicalAddress(byte[] address)'.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.Metadata.Conventions.ConstructorBindingConvention.ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext1 context) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IConventionModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IConventionModelBuilder modelBuilder) at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel() at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel() at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder) at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.<GetModel>b__1() at System.Lazy1.ViaFactory(LazyThreadSafetyMode mode)
at System.Lazy1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor) at System.Lazy1.CreateValue()
at System.Lazy1.get_Value() at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder) at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel() at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model() at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_3(IServiceProvider p) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSite(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope) at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider() at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance() at Microsoft.EntityFrameworkCore.Infrastructure.Internal.InfrastructureExtensions.GetService[TService](IInfrastructure1 accessor)
at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.get_Dependencies()
at Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.EnsureDeleted()
at EfTest.Program.Main(String[] args) in C:\Users\Name\source\repos\EfTest\EfTest\Program.cs:line 15

Further technical details

EF Core version: 3.0.0
Database provider: Microsoft.EntityFrameworkCore.InMemory
Target framework: .NET Core 3.0
Operating system: Windows 10
IDE: Visual Studio 2019 16.3.6

@ajcvickers ajcvickers changed the title In Memory Database errors when having IPAddress or PhysicalAddress Entity Properties Add built-in value converters for IPAddress or PhysicalAddress Nov 1, 2019
@ajcvickers ajcvickers added this to the Backlog milestone Nov 1, 2019
@ajcvickers ajcvickers added the good first issue This issue should be relatively straightforward to fix. label Nov 1, 2019
@ajcvickers
Copy link
Member

@tfadler This is because the in-memory provider doesn't handle these types by default. A workaround is to add value converters when using the in-memory database:

modelBuilder
    .Entity<NetworkStuff>()
    .Property(e => e.IpAddress1)
    .HasConversion(
        v => v.ToString(),
        v => IPAddress.Parse(v));
    
modelBuilder
    .Entity<NetworkStuff>()
    .Property(e => e.Mac1)
    .HasConversion(
        v => v.ToString(),
        v => PhysicalAddress.Parse(v));

I'm putting this issue on the backlog to make these (or similar) converters built-in so the conversion is done automatically for any provider that doesn't support these types natively.

@tfadler
Copy link
Author

tfadler commented Nov 1, 2019

@ajcvickers Yes that would be a good work around and is for just in memory database.

I was hoping to have an in memory database for some Integration Tests. My boss will likely want to still have those be native type in the actual (postgresql) database. So I can't put the conversions in my OnModelCreating() for my dbcontext.

I guess I could write a new dbcontext class (for ITs) that inherits my current one...so I can have access to the OnModelCreating() to put the conversions in....unless you know of another hook I can get access to modelBuilder with an Integration Test?

@ralmsdeveloper
Copy link
Contributor

@ajcvickers, I'll take this for me!

@ajcvickers
Copy link
Member

@tfadler IModelSource can be implemented to decouple OnModelCreating from the DbContext instance.

@AndriySvyryd
Copy link
Member

AndriySvyryd commented Nov 5, 2019

@tfadler You can add conditional code to OnModelCreating:

if (Database.IsInMemory())
{
    modelBuilder
        .Entity<NetworkStuff>()
        .Property(e => e.Mac1)
        .HasConversion(
            v => v.ToString(),
            v => PhysicalAddress.Parse(v));
}

ajcvickers pushed a commit that referenced this issue Apr 26, 2020
Add built-in value converters for IPAddress

Fixes #18662
@ajcvickers ajcvickers added closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. and removed good first issue This issue should be relatively straightforward to fix. labels Apr 26, 2020
@ajcvickers ajcvickers modified the milestones: Backlog, 5.0.0 Apr 26, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0, 5.0.0-preview5 May 11, 2020
@ajcvickers
Copy link
Member

Re-opening this as I hit issues as soon as I tried to create an example. Specifically, the column is created as nvarchar(max) by default:

CREATE TABLE [Users] (
          [Id] int NOT NULL IDENTITY,
          [Name] nvarchar(max) COLLATE German_PhoneBook_CI_AS NULL,
          [HomeAddress] nvarchar(max) NULL,
          CONSTRAINT [PK_Users] PRIMARY KEY ([Id])
      );

Also, a query like this:

context.Users.Where(e => e.HomeAddress == IPAddress.Loopback).ToList();

throws:

Unhandled exception. System.InvalidOperationException: Null TypeMapping in Sql Tree.
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.SqlTypeMappingVerifyingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlUnaryExpression.VisitChildren(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.VisitExtension(Expression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.SqlTypeMappingVerifyingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlBinaryExpression.VisitChildren(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.VisitExtension(Expression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.SqlTypeMappingVerifyingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.TranslateInternal(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalSqlTranslatingExpressionVisitor.Translate(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateExpression(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateLambdaExpression(ShapedQueryExpression shapedQueryExpression, LambdaExpression lambdaExpression)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.TranslateWhere(ShapedQueryExpression source, LambdaExpression predicate)
   at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Program.Main() in /home/ajcvickers/AllTogetherNow/Daily/Daily.cs:line 30

@ajcvickers ajcvickers reopened this Jun 3, 2020
@ajcvickers ajcvickers removed this from the 5.0.0-preview5 milestone Jun 3, 2020
@ajcvickers ajcvickers removed the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Jun 3, 2020
@ajcvickers ajcvickers added this to the 5.0.0 milestone Jun 5, 2020
@roji
Copy link
Member

roji commented Jun 6, 2020

Split out "Null TypeMapping in Sql Tree" to #21159 - it's a problem specific with the static readonly types on IPAddress. I don't believe it's a fundamental problem with our new IPAddress support - there's an easy workaround, we can probably deal with it separately (and even punt).

#21161 adds a size hint of 45 for the string representation of IPAddress.

Aside from all that, leaving this open until #20917 is merged.

@ajcvickers ajcvickers added the closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. label Jul 10, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0, 5.0.0-preview8 Jul 14, 2020
@ajcvickers ajcvickers modified the milestones: 5.0.0-preview8, 5.0.0 Nov 7, 2020
@simbadltd
Copy link

simbadltd commented Nov 25, 2021

Also you can override IModelCustomizer as a workaround and avoid adding test code into production one:

        public class TestModelCustomizer : ModelCustomizer
        {
            public TestModelCustomizer (ModelCustomizerDependencies dependencies)
                : base(dependencies)
            {
            }

            public override void Customize(ModelBuilder modelBuilder, DbContext context)
            {
                base.Customize(modelBuilder, context);
                modelBuilder
                        .Entity<NetworkStuff>()
                        .Property(e => e.Mac1)
                        .HasConversion(
                            v => v.ToString(),
                            v => PhysicalAddress.Parse(v));
            }
        }

And then the only thing you need is the correct registration:

            services.AddDbContext<FooDbContext>(builder =>
            {
                builder.ReplaceService<IModelCustomizer, TestModelCustomizer>();
                builder.UseInMemoryDatabase();
            });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported type-enhancement
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants