// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Linq;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
namespace Microsoft.AspNetCore.Identity.EntityFrameworkCore
{
///
/// Base class for the Entity Framework database context used for identity.
///
/// The type of the user objects.
public class IdentityUserContext : IdentityUserContext where TUser : IdentityUser
{
///
/// Initializes a new instance of .
///
/// The options to be used by a .
public IdentityUserContext(DbContextOptions options) : base(options) { }
///
/// Initializes a new instance of the class.
///
protected IdentityUserContext() { }
}
///
/// Base class for the Entity Framework database context used for identity.
///
/// The type of user objects.
/// The type of the primary key for users and roles.
public class IdentityUserContext : IdentityUserContext, IdentityUserLogin, IdentityUserToken>
where TUser : IdentityUser
where TKey : IEquatable
{
///
/// Initializes a new instance of the db context.
///
/// The options to be used by a .
public IdentityUserContext(DbContextOptions options) : base(options) { }
///
/// Initializes a new instance of the class.
///
protected IdentityUserContext() { }
}
///
/// Base class for the Entity Framework database context used for identity.
///
/// The type of user objects.
/// The type of the primary key for users and roles.
/// The type of the user claim object.
/// The type of the user login object.
/// The type of the user token object.
public abstract class IdentityUserContext : DbContext
where TUser : IdentityUser
where TKey : IEquatable
where TUserClaim : IdentityUserClaim
where TUserLogin : IdentityUserLogin
where TUserToken : IdentityUserToken
{
///
/// Initializes a new instance of the class.
///
/// The options to be used by a .
public IdentityUserContext(DbContextOptions options) : base(options) { }
///
/// Initializes a new instance of the class.
///
protected IdentityUserContext() { }
///
/// Gets or sets the of Users.
///
public DbSet Users { get; set; }
///
/// Gets or sets the of User claims.
///
public DbSet UserClaims { get; set; }
///
/// Gets or sets the of User logins.
///
public DbSet UserLogins { get; set; }
///
/// Gets or sets the of User tokens.
///
public DbSet UserTokens { get; set; }
private int GetMaxLengthForKeys()
{
// Need to get the actual application service provider, fallback will cause
// options to not work since IEnumerable don't flow across providers
var options = this.GetService()
.Extensions.OfType()
.FirstOrDefault()?.ApplicationServiceProvider
?.GetService>()
?.Value?.Stores;
return options != null ? options.MaxLengthForKeys : 0;
}
///
/// Configures the schema needed for the identity framework.
///
///
/// The builder being used to construct the model for this context.
///
protected override void OnModelCreating(ModelBuilder builder)
{
var maxKeyLength = GetMaxLengthForKeys();
builder.Entity(b =>
{
b.HasKey(u => u.Id);
b.HasIndex(u => u.NormalizedUserName).HasName("UserNameIndex").IsUnique();
b.HasIndex(u => u.NormalizedEmail).HasName("EmailIndex");
b.ToTable("AspNetUsers");
b.Property(u => u.ConcurrencyStamp).IsConcurrencyToken();
b.Property(u => u.UserName).HasMaxLength(256);
b.Property(u => u.NormalizedUserName).HasMaxLength(256);
b.Property(u => u.Email).HasMaxLength(256);
b.Property(u => u.NormalizedEmail).HasMaxLength(256);
b.HasMany().WithOne().HasForeignKey(uc => uc.UserId).IsRequired();
b.HasMany().WithOne().HasForeignKey(ul => ul.UserId).IsRequired();
b.HasMany().WithOne().HasForeignKey(ut => ut.UserId).IsRequired();
});
builder.Entity(b =>
{
b.HasKey(uc => uc.Id);
b.ToTable("AspNetUserClaims");
});
builder.Entity(b =>
{
b.HasKey(l => new { l.LoginProvider, l.ProviderKey });
if (maxKeyLength > 0)
{
b.Property(l => l.LoginProvider).HasMaxLength(maxKeyLength);
b.Property(l => l.ProviderKey).HasMaxLength(maxKeyLength);
}
b.ToTable("AspNetUserLogins");
});
builder.Entity(b =>
{
b.HasKey(t => new { t.UserId, t.LoginProvider, t.Name });
if (maxKeyLength > 0)
{
b.Property(t => t.LoginProvider).HasMaxLength(maxKeyLength);
b.Property(t => t.Name).HasMaxLength(maxKeyLength);
}
b.ToTable("AspNetUserTokens");
});
}
}
}