programing

ASP.NET ID DbContext 혼동

newsource 2023. 4. 20. 21:31

ASP.NET ID DbContext 혼동

기본 MVC 5 앱은 IdentityModels.cs에서 이 코드와 함께 제공됩니다. 이 코드는 모든 ASP용입니다.기본 템플릿에 대한 NET ID 작업:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }
}

Entity Framework에서 뷰를 사용하여 새로운 컨트롤러의 골격을 설정하고 "새로운 데이터 컨텍스트.." 대화 상자에서 다음과 같이 생성됩니다.

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;

namespace WebApplication1.Models
{
    public class AllTheOtherStuffDbContext : DbContext
    {
        // You can add custom code to this file. Changes will not be overwritten.
        // 
        // If you want Entity Framework to drop and regenerate your database
        // automatically whenever you change your model schema, please use data migrations.
        // For more information refer to the documentation:
        // http://msdn.microsoft.com/en-us/data/jj591621.aspx

        public AllTheOtherStuffDbContext() : base("name=AllTheOtherStuffDbContext")
        {
        }

        public System.Data.Entity.DbSet<WebApplication1.Models.Movie> Movies { get; set; }

    }
} 

EF를하여 다른 +이은 EF 에 자동 됩니다.public System.Data.Entity.DbSet<WebApplication1.Models.Movie> Movies { get; set; } - 이렇게요.

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;

namespace WebApplication1.Models
{
    public class AllTheOtherStuffDbContext : DbContext
    {
        // You can add custom code to this file. Changes will not be overwritten.
        // 
        // If you want Entity Framework to drop and regenerate your database
        // automatically whenever you change your model schema, please use data migrations.
        // For more information refer to the documentation:
        // http://msdn.microsoft.com/en-us/data/jj591621.aspx

        public AllTheOtherStuffDbContext() : base("name=AllTheOtherStuffDbContext")
        {
        }

        public System.Data.Entity.DbSet<WebApplication1.Models.Movie> Movies { get; set; }
        public System.Data.Entity.DbSet<WebApplication1.Models.Animal> Animals { get; set; }

    }
} 

ApplicationDbContext ('ASP'의 ) strup는 NET Identity에서 됩니다.IdentityDbContext은, 「」로부터 됩니다.DbContextAllOtherStuffDbContext 것을DbContext.

제 질문은 다음과 같습니다.

두 가지 중 것( 「 」 「 」 「 」 )ApplicationDbContext ★★★★★★★★★★★★★★★★★」AllOtherStuffDbContext 모든 에 사용해야 합니까른른른른른른른른른른른른른른른? autogenerated를 요?ApplicationDbContext 등급에서 없을 것입니다.DbContext니면면 ?? ?? ?? ?? ? ??? 한 번만 요.DbContext ( 둘 다 쓸 .ApplicationDbContext ★★★★★★★★★★★★★★★★★」AllOtherStuffDbContext나의앱??? ??「ASP」 「MVC 5」 「MVC 5」는 「ASP」라고 하는 것입니까?NET?

IdentityDbContext에서 상속되는 단일 컨텍스트클래스를 사용합니다.이렇게 하면 IdentityDbContext의 IdentityUser 및 역할과 클래스 간의 관계를 컨텍스트에서 인식할 수 있습니다.IdentityDbContext에는 오버헤드가 거의 없습니다.기본적으로 2개의 DbSet을 가진 일반 DbContext입니다.하나는 사용자용이고 다른 하나는 역할용입니다.

Stackoverflow에서의 빠른 검색인 IdentityDbContext에 대해 많은 혼란이 있습니다.다음 질문이 있습니다.
"왜 ASP인가?넷 아이덴티티 Db 블랙박스에 컨텍스트를 입력하시겠습니까?
Visual Studio 2013 AspNet Identity visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual visual?
MyDbContext와 IdentityDbContext의 결합"

이 모든 질문에 답하려면 IdentityDbContext는 DbContext에서 상속된 클래스일 뿐이라는 점을 이해해야 합니다.
IdentityDbContext 소스를 살펴보겠습니다.

/// <summary>
/// Base class for the Entity Framework database context used for identity.
/// </summary>
/// <typeparam name="TUser">The type of user objects.</typeparam>
/// <typeparam name="TRole">The type of role objects.</typeparam>
/// <typeparam name="TKey">The type of the primary key for users and roles.</typeparam>
/// <typeparam name="TUserClaim">The type of the user claim object.</typeparam>
/// <typeparam name="TUserRole">The type of the user role object.</typeparam>
/// <typeparam name="TUserLogin">The type of the user login object.</typeparam>
/// <typeparam name="TRoleClaim">The type of the role claim object.</typeparam>
/// <typeparam name="TUserToken">The type of the user token object.</typeparam>
public abstract class IdentityDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> : DbContext
    where TUser : IdentityUser<TKey, TUserClaim, TUserRole, TUserLogin>
    where TRole : IdentityRole<TKey, TUserRole, TRoleClaim>
    where TKey : IEquatable<TKey>
    where TUserClaim : IdentityUserClaim<TKey>
    where TUserRole : IdentityUserRole<TKey>
    where TUserLogin : IdentityUserLogin<TKey>
    where TRoleClaim : IdentityRoleClaim<TKey>
    where TUserToken : IdentityUserToken<TKey>
{
    /// <summary>
    /// Initializes a new instance of <see cref="IdentityDbContext"/>.
    /// </summary>
    /// <param name="options">The options to be used by a <see cref="DbContext"/>.</param>
    public IdentityDbContext(DbContextOptions options) : base(options)
    { }

    /// <summary>
    /// Initializes a new instance of the <see cref="IdentityDbContext" /> class.
    /// </summary>
    protected IdentityDbContext()
    { }

    /// <summary>
    /// Gets or sets the <see cref="DbSet{TEntity}"/> of Users.
    /// </summary>
    public DbSet<TUser> Users { get; set; }

    /// <summary>
    /// Gets or sets the <see cref="DbSet{TEntity}"/> of User claims.
    /// </summary>
    public DbSet<TUserClaim> UserClaims { get; set; }

    /// <summary>
    /// Gets or sets the <see cref="DbSet{TEntity}"/> of User logins.
    /// </summary>
    public DbSet<TUserLogin> UserLogins { get; set; }

    /// <summary>
    /// Gets or sets the <see cref="DbSet{TEntity}"/> of User roles.
    /// </summary>
    public DbSet<TUserRole> UserRoles { get; set; }

    /// <summary>
    /// Gets or sets the <see cref="DbSet{TEntity}"/> of User tokens.
    /// </summary>
    public DbSet<TUserToken> UserTokens { get; set; }

    /// <summary>
    /// Gets or sets the <see cref="DbSet{TEntity}"/> of roles.
    /// </summary>
    public DbSet<TRole> Roles { get; set; }

    /// <summary>
    /// Gets or sets the <see cref="DbSet{TEntity}"/> of role claims.
    /// </summary>
    public DbSet<TRoleClaim> RoleClaims { get; set; }

    /// <summary>
    /// Configures the schema needed for the identity framework.
    /// </summary>
    /// <param name="builder">
    /// The builder being used to construct the model for this context.
    /// </param>
    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<TUser>(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(u => u.Claims).WithOne().HasForeignKey(uc => uc.UserId).IsRequired();
            b.HasMany(u => u.Logins).WithOne().HasForeignKey(ul => ul.UserId).IsRequired();
            b.HasMany(u => u.Roles).WithOne().HasForeignKey(ur => ur.UserId).IsRequired();
        });

        builder.Entity<TRole>(b =>
        {
            b.HasKey(r => r.Id);
            b.HasIndex(r => r.NormalizedName).HasName("RoleNameIndex");
            b.ToTable("AspNetRoles");
            b.Property(r => r.ConcurrencyStamp).IsConcurrencyToken();

            b.Property(u => u.Name).HasMaxLength(256);
            b.Property(u => u.NormalizedName).HasMaxLength(256);

            b.HasMany(r => r.Users).WithOne().HasForeignKey(ur => ur.RoleId).IsRequired();
            b.HasMany(r => r.Claims).WithOne().HasForeignKey(rc => rc.RoleId).IsRequired();
        });

        builder.Entity<TUserClaim>(b => 
        {
            b.HasKey(uc => uc.Id);
            b.ToTable("AspNetUserClaims");
        });

        builder.Entity<TRoleClaim>(b => 
        {
            b.HasKey(rc => rc.Id);
            b.ToTable("AspNetRoleClaims");
        });

        builder.Entity<TUserRole>(b => 
        {
            b.HasKey(r => new { r.UserId, r.RoleId });
            b.ToTable("AspNetUserRoles");
        });

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

        builder.Entity<TUserToken>(b => 
        {
            b.HasKey(l => new { l.UserId, l.LoginProvider, l.Name });
            b.ToTable("AspNetUserTokens");
        });
    }
}

Based on the source code if we want to merge IdentityDbContext with our DbContext we have two options:

**First Option:**
Create a DbContext which inherits from IdentityDbContext and have access to the classes.
   public class ApplicationDbContext 
    : IdentityDbContext
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }

    static ApplicationDbContext()
    {
        Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    // Add additional items here as needed
}


추가 주의:

  1. 다음 솔루션을 사용하여 asp.net ID 기본 테이블 이름을 변경할 수도 있습니다.

     public class ApplicationDbContext : IdentityDbContext
     {    
         public ApplicationDbContext(): base("DefaultConnection")
         {
         }
    
         protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
         {
             base.OnModelCreating(modelBuilder);
             modelBuilder.Entity<IdentityUser>().ToTable("user");
             modelBuilder.Entity<ApplicationUser>().ToTable("user");
    
             modelBuilder.Entity<IdentityRole>().ToTable("role");
             modelBuilder.Entity<IdentityUserRole>().ToTable("userrole");
             modelBuilder.Entity<IdentityUserClaim>().ToTable("userclaim");
             modelBuilder.Entity<IdentityUserLogin>().ToTable("userlogin");
         }
     }
    
  2. 각 를 확장하고 ''와 같은 할 수 . '', ','', ...

     public class ApplicationRole : IdentityRole<string, ApplicationUserRole>
    

    { public ApplicationRole } {이것.ID = GUID.New Guid().ToString(); }

     public ApplicationRole(string name)
         : this()
     {
         this.Name = name;
     }
    
     // Add any custom Role properties/code here
    

    }

    // 커스텀 타입으로 표현해야 합니다.퍼블릭 클래스 ApplicationDbContext : IdentityDbContext <ApplicationUser, ApplicationUserRole, ApplicationUserClaim> {public ApplicationDbContext} {base("DefaultConnection}}} {}}} 。

     static ApplicationDbContext()
     {
         Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
     }
    
     public static ApplicationDbContext Create()
     {
         return new ApplicationDbContext();
     }
    
     // Add additional items here as needed
    

    } 시간을 절약하기 위해 AspNet Identity 2.0 Extensible Project Template를 사용하여 모든 클래스를 확장할 수 있습니다.

두 번째 옵션:(권장하지 않음)
모든 코드를 직접 작성하면 IdentityDbContext에서 상속할 필요가 없습니다.
따라서 기본적으로는 DbContext에서 상속하고 IdentityDbContext 소스 코드에서 커스터마이즈된 버전의 "OnModelCreating(ModelBuilder)"을 구현할 수 있습니다.

이것은 사람들에게 늦은 시작이지만, 아래는 저의 구현입니다.또한 KEY 기본유형을 변경하는 기능을 삭제하였습니다.상세한 내용은 다음 문서를 참조하십시오.

주의:
사용할 수 없다는 점에 유의하십시오.Guid's키를 찾아주세요.이것은 그들이 후드 아래에 있기 때문이다.Struct범용에서 변환할 수 있는 언박스는 없습니다.<TKey>파라미터를 지정합니다.

클래스는 다음과 같습니다.

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, string, CustomUserLogin, CustomUserRole, CustomUserClaim>
{
    #region <Constructors>

    public ApplicationDbContext() : base(Settings.ConnectionString.Database.AdministrativeAccess)
    {
    }

    #endregion

    #region <Properties>

    //public DbSet<Case> Case { get; set; }

    #endregion

    #region <Methods>

    #region

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        //modelBuilder.Configurations.Add(new ResourceConfiguration());
        //modelBuilder.Configurations.Add(new OperationsToRolesConfiguration());
    }

    #endregion

    #region

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }

    #endregion

    #endregion
}

    public class ApplicationUser : IdentityUser<string, CustomUserLogin, CustomUserRole, CustomUserClaim>
    {
        #region <Constructors>

        public ApplicationUser()
        {
            Init();
        }

        #endregion

        #region <Properties>

        [Required]
        [StringLength(250)]
        public string FirstName { get; set; }

        [Required]
        [StringLength(250)]
        public string LastName { get; set; }

        #endregion

        #region <Methods>

        #region private

        private void Init()
        {
            Id = Guid.Empty.ToString();
        }

        #endregion

        #region public

        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, string> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);

            // Add custom user claims here

            return userIdentity;
        }

        #endregion

        #endregion
    }

    public class CustomUserStore : UserStore<ApplicationUser, CustomRole, string, CustomUserLogin, CustomUserRole, CustomUserClaim>
    {
        #region <Constructors>

        public CustomUserStore(ApplicationDbContext context) : base(context)
        {
        }

        #endregion
    }

    public class CustomUserRole : IdentityUserRole<string>
    {
    }

    public class CustomUserLogin : IdentityUserLogin<string>
    {
    }

    public class CustomUserClaim : IdentityUserClaim<string> 
    { 
    }

    public class CustomRoleStore : RoleStore<CustomRole, string, CustomUserRole>
    {
        #region <Constructors>

        public CustomRoleStore(ApplicationDbContext context) : base(context)
        {
        } 

        #endregion
    }

    public class CustomRole : IdentityRole<string, CustomUserRole>
    {
        #region <Constructors>

        public CustomRole() { }
        public CustomRole(string name) 
        { 
            Name = name; 
        }

        #endregion
    }

IdentityDbContext의 추상화를 드릴다운하면 파생된 DbContext와 동일하게 보입니다.가장 쉬운 방법은 Olav의 답변입니다.만, 작성 대상을 보다 제어해, Identity 패키지에의 의존을 줄이고 싶은 경우는, 이쪽에서 질문의 답변을 봐 주세요.링크를 따라가면 코드 예가 있지만 요약하면 필요한 DbSet을 자신의 DbContext 하위 클래스에 추가하는 것입니다.

언급URL : https://stackoverflow.com/questions/19902756/asp-net-identity-dbcontext-confusion