方法FindByLoginAsync无法与AspNetCore.Identity一起正常工作

时间:2017-03-24 13:47:28

标签: asp.net-core asp.net-identity-3

我在AspNetCore.Identity应用程序中使用了Asp.Net Core,我想调用名为FindByLoginAsync的方法,但结果始终为NULL。

版本:

Microsoft.AspNetCore.Identity.EntityFrameworkCore (1.1.1)
Microsoft.AspNetCore.Identity (1.1.1)

代码:

var loginProvider = "Github"
var providerKey = "1234567";
var user = await _userManager.FindByLoginAsync(loginProvider, providerKey);

此记录存在于数据库中,但此方法始终返回NULL。

我试过跟踪SQL查询,我得到了这个:

exec sp_executesql N'SELECT TOP(1) [e].[ProviderKey], [e].[LoginProvider], [e].[ProviderDisplayName], [e].[UserId]
FROM [UserLogins] AS [e]
WHERE ([e].[ProviderKey] = @__get_Item_0) AND ([e].[LoginProvider] = @__get_Item_1)',N'@__get_Item_0 nvarchar(450),@__get_Item_1 nvarchar(450)',@__get_Item_0=N'Github',@__get_Item_1=N'1234567'

我的SQL查询与[e].[LoginProvider]的值providerKey[e].[ProviderKey]的值loginProvider类似。

应用程序DbContext

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, int>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }

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

            builder.Entity<ApplicationUser>(i =>
            {
                i.ToTable("Users");
                i.HasKey(x => x.Id);
            });
            builder.Entity<ApplicationRole>(i =>
            {
                i.ToTable("Roles");
                i.HasKey(x => x.Id);
            });
            builder.Entity<IdentityUserRole<int>>(i =>
            {
                i.ToTable("UserRoles");
                i.HasKey(x => new { x.RoleId, x.UserId });
            });
            builder.Entity<IdentityUserLogin<int>>(i =>
            {
                i.ToTable("UserLogins");
                i.HasKey(x => new { x.ProviderKey, x.LoginProvider });
            });
            builder.Entity<IdentityRoleClaim<int>>(i =>
            {
                i.ToTable("RoleClaims");
                i.HasKey(x => x.Id);
            });
            builder.Entity<IdentityUserClaim<int>>(i =>
            {
                i.ToTable("UserClaims");
                i.HasKey(x => x.Id);
            });
            builder.Entity<IdentityUserToken<int>>(i =>
            {
                i.ToTable("UserTokens");
                i.HasKey(x => x.UserId);
            });
        }
    }

IdentityUser的实现,IdentityRole

public class ApplicationUser : IdentityUser<int>
{

}

public class ApplicationRole : IdentityRole<int>
{
}

我该如何解决这个问题?这种行为怎么可能? :)

谢谢。

1 个答案:

答案 0 :(得分:1)

在注册实体IdentityUserLogin时,您的主键顺序不正确。将其更改为此

builder.Entity<IdentityUserLogin<int>>(i =>
{
    i.ToTable("UserLogins");
    i.HasKey(x => new { x.LoginProvider, x.ProviderKey });
});

这是修复,现在背后的理由。

在版本1.1.1中,方法UserStore.FindByLoginAsync使用方法DbSet.FindAsync,它接受​​主键的有序值数组。订单必须遵循实体注册中使用的订单。

public async virtual Task<TUser> FindByLoginAsync(string loginProvider, string providerKey,
        CancellationToken cancellationToken = default(CancellationToken))
{
   ...
   var userLogin = await UserLogins.FindAsync(new object[] { loginProvider, providerKey }, cancellationToken);
   ...
}

在默认实现中,主键在correct order

中注册
builder.Entity<TUserLogin>(b =>
{
    b.HasKey(l => new { l.LoginProvider, l.ProviderKey });
    b.ToTable("AspNetUserLogins");
});