系统无法找到适合实体类型“BoundingBox”的构造函数。

3
我正在使用asp.net core 3.1与entity framework core cosmos db提供程序。在我的模型中,我有一个类型为指针的LocationCoordinates属性。当检查用户是否存在时,我遇到了错误。
我在我的模型类ApplicationUser中使用point类。Microsoft.Azure.Cosmos.Spatial.Point用于保存坐标纬度和经度。
我正在使用CosmosDb包https://www.nuget.org/packages/Microsoft.EntityFrameworkCore.Cosmos/ 请帮忙。
using Microsoft.AspNetCore.Identity;
using Microsoft.Azure.Cosmos.Spatial;

namespace TestApp_Backend_API.Entities
{
    public class ApplicationUser : IdentityUser
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string ZipCode { get; set; }

        public Point LocationCoordinates { get; set; }
    }
}

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using TestApp_Backend_API.Entities;

namespace TestApp_Backend_API.DbContexts
{
    public class TestAppContext : IdentityDbContext<ApplicationUser>
    {
        public TestAppContext(DbContextOptions options)
            : base(options)
        {
        }

        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);

            builder.HasDefaultContainer("Users");
            builder.Entity<IdentityUser>().ToContainer("Users");
            builder.Entity<ApplicationUser>().ToContainer("Users");
            builder.Entity<IdentityUserRole<string>>().ToContainer("UserRoles");
            builder.Entity<IdentityUserLogin<string>>().ToContainer("UserLogins");
            builder.Entity<IdentityUserClaim<string>>().ToContainer("UserClaims");
            builder.Entity<IdentityRole>().ToContainer("Roles");
            builder.Entity<IdentityUserToken<string>>().ToContainer("UserTokens");
        }
    }
}

调用此方法时出现错误:

var user = await _userManager.FindByEmailAsync(email);

错误:

System.InvalidOperationException: No suitable constructor found for entity type 'BoundingBox'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'min', 'max' in 'BoundingBox(Position min, Position max)'.
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.ConstructorBindingConvention.ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext`1 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.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.CallSiteVisitor`2.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.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.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.CallSiteVisitor`2.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.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.Set[TEntity]()
   at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9.get_UsersSet()
   at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9.get_Users()
   at Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9.FindByEmailAsync(String normalizedEmail, CancellationToken cancellationToken)
   at Microsoft.AspNetCore.Identity.UserManager`1.FindByEmailAsync(String email)
   at TestApp_Backend_API.Services.AuthRepository.IsEmailExistsAsync(String email) in D:\Ali\Projects\TestApp-Backend\TestApp-BackendServices\TestApp-Backend-API\Services\AuthRepository.cs:line 303
   at TestApp_Backend_API.Controllers.AuthController.SendEmailVerificationToken(SendEmailVerificationTokenDto dto) in D:\Ali\Projects\TestApp-Backend\TestApp-BackendServices\TestApp-Backend-API\Controllers\AuthController.cs:line 317
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Logged|12_1(ControllerActionInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   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 where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   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 Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

1
请查看 https://github.com/dotnet/efcore/issues/15896 和 https://github.com/dotnet/efcore/issues/14336。 - Gaurav Mantri
请问您能否提供解决方案? - Julia
我正在使用asp.net core 3.1。 - Julia
我认为在cosmosDB实体中不能使用Point,只能使用普通对象。 - Roel
2个回答

2
您正在使用带有CosmosDB的Entity Framework Core(EF Core 3?)。

您想要使用CosmosDB自己的空间类型与EF Core。

然而,截至2021年末,EF Core仍不支持此功能。

作为解决方法:

  • 将您对空间类型的使用更改为计算属性,而不是存储属性,并使用[NotMapped],以便EF不会尝试绑定它们。
  • 您仍需要在某个地方存储原始值。

像这样:

    public class ApplicationUser : IdentityUser
    {
        public string FirstName { get; set; }

        public string LastName { get; set; }

        public string ZipCode { get; set; }

        public double Latitude  { get; set; }
        public double Longitude { get; set; }

        [NotMapped]
        public Point LocationCoordinates
        {
            get => new Point( this.Latitude, this.Longitude );
            set
            {
                this.Latitude  = value.Position.Latitude;
                this.Longitude = value.Position.Longitude;
            }
        }
    }

@RanadheerReddy CosmosDB 支持数组类型,但我不知道 EF Core 3.x 在多大程度上支持它。否则,为了安全起见,我建议将其存储为序列化字符串。 - Dai
谢谢。这样会更好,也更容易。请问您能否澄清一件事?如果这些空间类型不受支持,那么这篇文章是关于什么的?https://learn.microsoft.com/en-us/azure/cosmos-db/sql/sql-query-geospatial-intro - Ranadheer Reddy
1
@RanadheerReddy 那篇文章是指在不通过Entity Framework的情况下直接使用CosmosDB客户端库时,使用CosmosDB的地理空间类型。EF是对不同数据源的高级抽象,所有抽象必然意味着妥协某些东西,在EF的情况下,它们妥协了对数据库特定类型的支持(尽管EF直接支持SQL Server的地理空间类型,但这只是因为他们进行了特殊处理)。换句话说:您不需要使用EF来使用CosmosDB。 - Dai
如果文章中提供了这样的澄清,那将是非常好的。非常感谢您采取这样的举措。 - Ranadheer Reddy
1
@RanadheerReddy 如果您能点个赞,以示对我的主动行动的支持,我将不胜感激 ;) - Dai
显示剩余2条评论

-1
BoundingBox 创建一个私有的无参构造函数。

在ApplicationUser类中? - Julia
BoundingBox 类中。 - Mehrdad
1
作为你的异常信息,你有一个。 - Mehrdad
1
我在我的模型中使用点类。Microsoft.Azure.Cosmos.Spatial.Point 用于保存纬度和经度坐标。 - Julia
1
不要使用点作为CosmosDB实体,因为那是不合适的。 - Roel
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接