无法在模式“”中为实体“OpenIddictApplication”使用表“OpenIddictApplications”,因为它正在用于另一个实体

Posted

技术标签:

【中文标题】无法在模式“”中为实体“OpenIddictApplication”使用表“OpenIddictApplications”,因为它正在用于另一个实体【英文标题】:Cannot use table 'OpenIddictApplications' in schema '' for entity 'OpenIddictApplication' since it is being used for another entity 【发布时间】:2017-09-25 16:30:55 【问题描述】:

我正在尝试使用 OpenIddict 从 asp.net 核心应用程序获取令牌。

当我从我的端点请求一个令牌时,我得到了这个异常:

System.InvalidOperationException:无法在架构“”中为实体“OpenIddictApplication”使用表“OpenIddictApplications”,因为它正用于另一个实体。 在 Microsoft.EntityFrameworkCore.Internal.ModelValidator.ShowError(字符串消息) 在 Microsoft.EntityFrameworkCore.Internal.RelationalModelValidator.EnsureDistinctTableNames(IModel 模型) 在 Microsoft.EntityFrameworkCore.Internal.RelationalModelValidator.Validate(IModel 模型) 在 Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext 上下文,IConventionSetBuilder 约定集生成器,IModelValidator 验证器) 在 System.Collections.Concurrent.ConcurrentDictionary2.GetOrAdd(TKey key, Func2 valueFactory) 在 Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel() 在 Microsoft.EntityFrameworkCore.Internal.LazyRef1.get_Value() at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServiceCollectionExtensions.<>c.<AddQuery>b__1_3(IServiceProvider p) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider) at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure1 访问器) 在 Microsoft.EntityFrameworkCore.DbContext.get_QueryProvider() 在 Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.<.ctor>b__3_0() at Microsoft.EntityFrameworkCore.Internal.LazyRef1.get_Value() 在 Microsoft.EntityFrameworkCore.Internal.InternalDbSet1.System.Linq.IQueryable.get_Provider() at System.Linq.Queryable.SingleOrDefault[TSource](IQueryable1 源,Expression`1 谓词) 在 C:\Users\Enrique_Garcia\Desktop\OpenID\OpenID\Controllers\AuthorizeController.cs:line 35 中的 OpenID.Controllers.AuthorizeController.d__2.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__27.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__25.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext 上下文) 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(状态&下一个,范围&范围,对象&状态,布尔& isCompleted) 在 Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.d__22.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() ....

已经看到 this 但我没有使用 Asp.Net Identity

配置服务:

 public void ConfigureServices(IServiceCollection services)
    
        // Add framework services.
        services.AddMvc();
        services.AddDbContext<UniverContext>(options =>
        
            options.UseSqlServer(Configuration["Data:ConnectionString"]);
            options.UseOpenIddict();
        );

        services.AddOpenIddict(options =>
        
            options.AddEntityFrameworkCoreStores<UniverContext>();
            options.AddMvcBinders();
            options.EnableTokenEndpoint("/connect/token");
            options.AllowPasswordFlow().AllowRefreshTokenFlow();
            options.SetAccessTokenLifetime(TimeSpan.FromMinutes(1));
            options.SetRefreshTokenLifetime(TimeSpan.FromMinutes(2));
            options.DisableHttpsRequirement();
            options.UseJsonWebTokens();
            options.AddEphemeralSigningKey();

        );
    

配置:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env, 
  ILoggerFactory loggerFactory)
    
        app.UseDeveloperExceptionPage();
        app.UseOpenIddict();

        JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear();
        JwtSecurityTokenHandler.DefaultOutboundClaimTypeMap.Clear();

        app.UseJwtBearerAuthentication(new JwtBearerOptions
        
            Authority = "http://localhost:5000",
            Audience = "resource_server",
            RequireHttpsMetadata = false,
            TokenValidationParameters = new TokenValidationParameters
            
                NameClaimType = OpenIdConnectConstants.Claims.Subject,
                RoleClaimType = OpenIdConnectConstants.Claims.Role
            
        );

        loggerFactory.AddConsole(Configuration.GetSection("Logging"));
        loggerFactory.AddDebug();

        app.UseMvcWithDefaultRoute();
        app.UseWelcomePage();
    

提前致谢。

这是我的 UniverContext 类:

public partial class UniverContext : DbContext

    public virtual DbSet<Alumno> Alumno  get; set; 
    public virtual DbSet<AlumnoInscrito> AlumnoInscrito  get; set; 
    public virtual DbSet<Genero> Genero  get; set; 
    public virtual DbSet<OfertaEducativa> OfertaEducativa  get; set; 
    public virtual DbSet<OpenIddictApplications> OpenIddictApplications  get; set; 
    public virtual DbSet<OpenIddictAuthorizations> OpenIddictAuthorizations  get; set; 
    public virtual DbSet<OpenIddictScopes> OpenIddictScopes  get; set; 
    public virtual DbSet<OpenIddictTokens> OpenIddictTokens  get; set; 
    public virtual DbSet<Usuario> Usuario  get; set; 
    public virtual DbSet<UsuarioDetalle> UsuarioDetalle  get; set; 

    public UniverContext(DbContextOptions<UniverContext> options) : base(options)  

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    
        //modelBuilder.UseOpenIddict();

        modelBuilder.Entity<Alumno>(entity =>
        
            entity.HasIndex(e => e.GeneroId)
                .HasName("IX_Alumno_GeneroId");

            entity.Property(e => e.AlumnoId).ValueGeneratedNever();

            entity.Property(e => e.GeneroId).HasDefaultValueSql("0");

            entity.Property(e => e.Nombre).IsRequired();

            entity.HasOne(d => d.Genero)
                .WithMany(p => p.Alumno)
                .HasForeignKey(d => d.GeneroId);
        );

        modelBuilder.Entity<AlumnoInscrito>(entity =>
        
            entity.HasKey(e => new  e.AlumnoId, e.OfertaEducativaId )
                .HasName("PK_AlumnoInscrito");

            entity.HasIndex(e => e.OfertaEducativaId)
                .HasName("IX_AlumnoInscrito_OfertaEducativaId");

            entity.HasOne(d => d.Alumno)
                .WithMany(p => p.AlumnoInscrito)
                .HasForeignKey(d => d.AlumnoId);

            entity.HasOne(d => d.OfertaEducativa)
                .WithMany(p => p.AlumnoInscrito)
                .HasForeignKey(d => d.OfertaEducativaId);

            entity.HasOne(d => d.Usuario)
                .WithMany(p => p.AlumnoInscrito)
                .HasForeignKey(d => d.UsuarioId)
                .OnDelete(DeleteBehavior.Restrict)
                .HasConstraintName("FK_AlumnoInscrito_Usuario");
        );

        modelBuilder.Entity<Genero>(entity =>
        
            entity.Property(e => e.GeneroId).ValueGeneratedNever();

            entity.Property(e => e.Descripcion).IsRequired();
        );

        modelBuilder.Entity<OfertaEducativa>(entity =>
        
            entity.Property(e => e.OfertaEducativaId).ValueGeneratedNever();

            entity.Property(e => e.Descripcion).IsRequired();
        );

        modelBuilder.Entity<OpenIddictApplications>(entity =>
        
            entity.HasIndex(e => e.ClientId)
                .HasName("IX_OpenIddictApplications_ClientId")
                .IsUnique();

            entity.Property(e => e.Id).HasMaxLength(450);

            entity.Property(e => e.ClientId)
                .IsRequired()
                .HasMaxLength(450);
        );

        modelBuilder.Entity<OpenIddictAuthorizations>(entity =>
        
            entity.HasIndex(e => e.ApplicationId)
                .HasName("IX_OpenIddictAuthorizations_ApplicationId");

            entity.Property(e => e.Id).HasMaxLength(450);

            entity.Property(e => e.ApplicationId).HasMaxLength(450);

            entity.HasOne(d => d.Application)
                .WithMany(p => p.OpenIddictAuthorizations)
                .HasForeignKey(d => d.ApplicationId);
        );

        modelBuilder.Entity<OpenIddictScopes>(entity =>
        
            entity.Property(e => e.Id).HasMaxLength(450);
        );

        modelBuilder.Entity<OpenIddictTokens>(entity =>
        
            entity.HasIndex(e => e.ApplicationId)
                .HasName("IX_OpenIddictTokens_ApplicationId");

            entity.HasIndex(e => e.AuthorizationId)
                .HasName("IX_OpenIddictTokens_AuthorizationId");

            entity.Property(e => e.Id).HasMaxLength(450);

            entity.Property(e => e.ApplicationId).HasMaxLength(450);

            entity.Property(e => e.AuthorizationId).HasMaxLength(450);

            entity.HasOne(d => d.Application)
                .WithMany(p => p.OpenIddictTokens)
                .HasForeignKey(d => d.ApplicationId);

            entity.HasOne(d => d.Authorization)
                .WithMany(p => p.OpenIddictTokens)
                .HasForeignKey(d => d.AuthorizationId);
        );

        modelBuilder.Entity<Usuario>(entity =>
        
            entity.Property(e => e.UsuarioId).HasDefaultValueSql("0");

            entity.Property(e => e.Nombre).IsRequired();

            entity.Property(e => e.Paterno)
                .IsRequired()
                .HasDefaultValueSql("N''");
        );

        modelBuilder.Entity<UsuarioDetalle>(entity =>
        
            entity.HasKey(e => e.UsuarioId)
                .HasName("PK_UsuarioDetalle");

            entity.Property(e => e.UsuarioId).ValueGeneratedNever();

            entity.Property(e => e.Password)
                .IsRequired()
                .HasColumnType("varchar(50)");

            entity.HasOne(d => d.Usuario)
                .WithOne(p => p.UsuarioDetalle)
                .HasForeignKey<UsuarioDetalle>(d => d.UsuarioId)
                .OnDelete(DeleteBehavior.Restrict)
                .HasConstraintName("FK_UsuarioDetalle_Usuario");
        );
    

而我的 csproj 文件包含的是:

<PropertyGroup>
<TargetFramework>netcoreapp1.1</TargetFramework>
<AspNetContribOpenIdExtensionsVersion>1.0.0-*</AspNetContribOpenIdExtensionsVersion>
<OpenIddictVersion>1.0.0-*</OpenIddictVersion>
<PackageTargetFallback>portable-net45+win8</PackageTargetFallback>

 <PackageReference Include="AspNet.Security.OAuth.Validation" Version="1.0.0-rtm-0255" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="1.1.1" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer.Design" Version="1.1.1" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="1.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.1" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="1.1.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="1.1.0" />
<PackageReference Include="OpenIddict" Version="$(OpenIddictVersion)" />
<PackageReference Include="OpenIddict.EntityFrameworkCore" Version="$(OpenIddictVersion)" />
<PackageReference Include="OpenIddict.Mvc" Version="$(OpenIddictVersion)" />

openiddict 版本的包是 1.0.0-beta2-0607

我正在尝试并且有效的是这是我的 AuthorizationController:

 if (request.Username != "email@email.com")
            
                return BadRequest(new OpenIdConnectResponse
                
                    Error = OpenIdConnectConstants.Errors.InvalidGrant,
                    ErrorDescription = "The username/password couple is invalid"
                );
            

            if (request.Password != "123456+")
            
                return BadRequest(new OpenIdConnectResponse
                
                    Error = OpenIdConnectConstants.Errors.InvalidGrant,
                    ErrorDescription = "The username/password couple is invalid"
                );
            

但是在 Startup 类中注册我的 DbContext 后,我​​正在尝试使用数据库用户的类似内容:

 var user = _context.Usuario.SingleOrDefault(x => x.UsuarioId == int.Parse(request.Username));

在这一行中,我得到了描述的错误。

如果您想查看我的 AuthorizationController,我创建了一个 repo,谢谢。

【问题讨论】:

能否分享您的UniverContext 以及您正在使用的确切软件包版本? 当然,已经添加。泰。 【参考方案1】:

这个例外对我来说很清楚:当您调用 options.AddOpenIddict() 时,OpenIddict 注册了默认实体,但您自己的 DbContext 定义了最终使用相同表名的不同实体 (OpenIddictApplications/OpenIddictAuthorizations/OpenIddictScopes /OpenIddictTokens),由于实体类型不同,被EntityFramework视为非法操作。

你有两个选项来解决这个问题:

使用默认的 OpenIddict 实体(例如 OpenIddictApplicationOpenIddictApplications)。 告诉 OpenIddict 您更喜欢使用自己的实体而不是内置实体:
// Register the OpenIddict services.
services.AddOpenIddict(options =>

    options.UseEntityFrameworkCore()
           .UseDbContext<ApplicationDbContext>()
           .ReplaceDefaultEntities<OpenIddictApplications, OpenIddictAuthorizations, OpenIddictScopes, OpenIddictTokens, string>();

    // ...
);

【讨论】:

对不起,我一直很忙。 谢谢,我明白你的回答。事实上,当我第一次迁移时,我注意到 OpenIddict 表名是复数形式。我从头开始制作了一个新项目,重要的是我正在使用 efcore 中的 dbfirst 方法,在创建 AuthorizeController 之后,我在包管理器控制台中使用 Add-Migration 命令进行了迁移,当我查看生成的文件时,我发现了每个表名它是复数形式:migrationBuilder.CreateTable( name: "OpenIddictApplications", columns: table => new... 我明白了,但我想知道哪个是正确的方法 如果你想看的话,我创建了另一个repo。 Ty 进阶。

以上是关于无法在模式“”中为实体“OpenIddictApplication”使用表“OpenIddictApplications”,因为它正在用于另一个实体的主要内容,如果未能解决你的问题,请参考以下文章

无法在类库中为实体框架启用迁移

在休眠中为同一实体的 MySQL 和 SQL 服务器配置差异表名称

如何在 Shopware 6 中为订单添加自定义字段?

如何在 Spring Boot 中为 DB2 连接在数据源中设置模式

无法在 SpEL 中为 Spring Data MongoDB 集合名称解析 bean

无法在我的 iPhone 应用程序中为横向设置 SplashScreen