Microsoft.AspNet.Identity.EntityFramework/IdentityDbContext.cs 源码:

  其中涉及到用户信息表、用户角色表的相关操作。

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Common;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Infrastructure.Annotations;
using System.Data.Entity.Validation;
using System.Data.SqlClient;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq; namespace Microsoft.AspNet.Identity.EntityFramework
{
/// <summary>
/// Default db context that uses the default entity types
/// </summary>
public class IdentityDbContext :
IdentityDbContext<IdentityUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
{
/// <summary>
/// Default constructor which uses the DefaultConnection
/// </summary>
public IdentityDbContext()
: this("DefaultConnection")
{
} /// <summary>
/// Constructor which takes the connection string to use
/// </summary>
/// <param name="nameOrConnectionString"></param>
public IdentityDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
} /// <summary>
/// Constructs a new context instance using the existing connection to connect to a database, and initializes it from
/// the given model. The connection will not be disposed when the context is disposed if contextOwnsConnection is
/// false.
/// </summary>
/// <param name="existingConnection">An existing connection to use for the new context.</param>
/// <param name="model">The model that will back this context.</param>
/// <param name="contextOwnsConnection">
/// Constructs a new context instance using the existing connection to connect to a
/// database, and initializes it from the given model. The connection will not be disposed when the context is
/// disposed if contextOwnsConnection is false.
/// </param>
public IdentityDbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
: base(existingConnection, model, contextOwnsConnection)
{
}
} /// <summary>
/// DbContext which uses a custom user entity with a string primary key
/// </summary>
/// <typeparam name="TUser"></typeparam>
public class IdentityDbContext<TUser> :
IdentityDbContext<TUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
where TUser : IdentityUser
{
/// <summary>
/// Default constructor which uses the DefaultConnection
/// </summary>
public IdentityDbContext()
: this("DefaultConnection")
{
} /// <summary>
/// Constructor which takes the connection string to use
/// </summary>
/// <param name="nameOrConnectionString"></param>
public IdentityDbContext(string nameOrConnectionString)
: this(nameOrConnectionString, true)
{
} /// <summary>
/// Constructor which takes the connection string to use
/// </summary>
/// <param name="nameOrConnectionString"></param>
/// <param name="throwIfV1Schema">Will throw an exception if the schema matches that of Identity 1.0.0</param>
public IdentityDbContext(string nameOrConnectionString, bool throwIfV1Schema)
: base(nameOrConnectionString)
{
if (throwIfV1Schema && IsIdentityV1Schema(this))
{
throw new InvalidOperationException(IdentityResources.IdentityV1SchemaError);
}
} /// <summary>
/// Constructs a new context instance using the existing connection to connect to a database, and initializes it from
/// the given model. The connection will not be disposed when the context is disposed if contextOwnsConnection is
/// false.
/// </summary>
/// <param name="existingConnection">An existing connection to use for the new context.</param>
/// <param name="model">The model that will back this context.</param>
/// <param name="contextOwnsConnection">
/// Constructs a new context instance using the existing connection to connect to a
/// database, and initializes it from the given model. The connection will not be disposed when the context is
/// disposed if contextOwnsConnection is false.
/// </param>
public IdentityDbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
: base(existingConnection, model, contextOwnsConnection)
{
} internal static bool IsIdentityV1Schema(DbContext db)
{
var originalConnection = db.Database.Connection as SqlConnection;
// Give up and assume its ok if its not a sql connection
if (originalConnection == null)
{
return false;
} if (db.Database.Exists())
{
using (var tempConnection = new SqlConnection(originalConnection.ConnectionString))
{
tempConnection.Open();
return
VerifyColumns(tempConnection, "AspNetUsers", "Id", "UserName", "PasswordHash", "SecurityStamp",
"Discriminator") &&
VerifyColumns(tempConnection, "AspNetRoles", "Id", "Name") &&
VerifyColumns(tempConnection, "AspNetUserRoles", "UserId", "RoleId") &&
VerifyColumns(tempConnection, "AspNetUserClaims", "Id", "ClaimType", "ClaimValue", "User_Id") &&
VerifyColumns(tempConnection, "AspNetUserLogins", "UserId", "ProviderKey", "LoginProvider");
}
} return false;
} [SuppressMessage("Microsoft.Security", "CA2100:Review SQL queries for security vulnerabilities",
Justification = "Reviewed")]
internal static bool VerifyColumns(SqlConnection conn, string table, params string[] columns)
{
var tableColumns = new List<string>();
using (
var command =
new SqlCommand("SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS where TABLE_NAME=@Table", conn))
{
command.Parameters.Add(new SqlParameter("Table", table));
using (var reader = command.ExecuteReader())
{
while (reader.Read())
{
// Add all the columns from the table
tableColumns.Add(reader.GetString());
}
}
}
// Make sure that we find all the expected columns
return columns.All(tableColumns.Contains);
}
} /// <summary>
/// IdentityDbContext of IdentityUsers
/// </summary>
/// <typeparam name="TUser"></typeparam>
/// <typeparam name="TRole"></typeparam>
/// <typeparam name="TKey"></typeparam>
/// <typeparam name="TUserLogin"></typeparam>
/// <typeparam name="TUserRole"></typeparam>
/// <typeparam name="TUserClaim"></typeparam>
public class IdentityDbContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim> : DbContext
where TUser : IdentityUser<TKey, TUserLogin, TUserRole, TUserClaim>
where TRole : IdentityRole<TKey, TUserRole>
where TUserLogin : IdentityUserLogin<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserClaim : IdentityUserClaim<TKey>
{
/// <summary>
/// Default constructor which uses the "DefaultConnection" connectionString
/// </summary>
public IdentityDbContext()
: this("DefaultConnection")
{
} /// <summary>
/// Constructor which takes the connection string to use
/// </summary>
/// <param name="nameOrConnectionString"></param>
public IdentityDbContext(string nameOrConnectionString)
: base(nameOrConnectionString)
{
} /// <summary>
/// Constructs a new context instance using the existing connection to connect to a database, and initializes it from
/// the given model. The connection will not be disposed when the context is disposed if contextOwnsConnection is
/// false.
/// </summary>
/// <param name="existingConnection">An existing connection to use for the new context.</param>
/// <param name="model">The model that will back this context.</param>
/// <param name="contextOwnsConnection">
/// Constructs a new context instance using the existing connection to connect to a
/// database, and initializes it from the given model. The connection will not be disposed when the context is
/// disposed if contextOwnsConnection is false.
/// </param>
public IdentityDbContext(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection)
: base(existingConnection, model, contextOwnsConnection)
{
} /// <summary>
/// EntitySet of Users
/// </summary>
public virtual IDbSet<TUser> Users { get; set; } /// <summary>
/// EntitySet of Roles
/// </summary>
public virtual IDbSet<TRole> Roles { get; set; } /// <summary>
/// If true validates that emails are unique
/// </summary>
public bool RequireUniqueEmail { get; set; } /// <summary>
/// Maps table names, and sets up relationships between the various user entities
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if (modelBuilder == null)
{
throw new ArgumentNullException("modelBuilder");
} // Needed to ensure subclasses share the same table
var user = modelBuilder.Entity<TUser>()
.ToTable("AspNetUsers");
user.HasMany(u => u.Roles).WithRequired().HasForeignKey(ur => ur.UserId);
user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
user.Property(u => u.UserName)
.IsRequired()
.HasMaxLength()
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true })); // CONSIDER: u.Email is Required if set on options?
user.Property(u => u.Email).HasMaxLength(); modelBuilder.Entity<TUserRole>()
.HasKey(r => new { r.UserId, r.RoleId })
.ToTable("AspNetUserRoles"); modelBuilder.Entity<TUserLogin>()
.HasKey(l => new { l.LoginProvider, l.ProviderKey, l.UserId })
.ToTable("AspNetUserLogins"); modelBuilder.Entity<TUserClaim>()
.ToTable("AspNetUserClaims"); var role = modelBuilder.Entity<TRole>()
.ToTable("AspNetRoles");
role.Property(r => r.Name)
.IsRequired()
.HasMaxLength()
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("RoleNameIndex") { IsUnique = true }));
role.HasMany(r => r.Users).WithRequired().HasForeignKey(ur => ur.RoleId);
} /// <summary>
/// Validates that UserNames are unique and case insenstive
/// </summary>
/// <param name="entityEntry"></param>
/// <param name="items"></param>
/// <returns></returns>
protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry,
IDictionary<object, object> items)
{
if (entityEntry != null && entityEntry.State == EntityState.Added)
{
var errors = new List<DbValidationError>();
var user = entityEntry.Entity as TUser;
//check for uniqueness of user name and email
if (user != null)
{
if (Users.Any(u => String.Equals(u.UserName, user.UserName)))
{
errors.Add(new DbValidationError("User",
String.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateUserName, user.UserName)));
}
if (RequireUniqueEmail && Users.Any(u => String.Equals(u.Email, user.Email)))
{
errors.Add(new DbValidationError("User",
String.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateEmail, user.Email)));
}
}
else
{
var role = entityEntry.Entity as TRole;
//check for uniqueness of role name
if (role != null && Roles.Any(r => String.Equals(r.Name, role.Name)))
{
errors.Add(new DbValidationError("Role",
String.Format(CultureInfo.CurrentCulture, IdentityResources.RoleAlreadyExists, role.Name)));
}
}
if (errors.Any())
{
return new DbEntityValidationResult(entityEntry, errors);
}
}
return base.ValidateEntity(entityEntry, items);
}
}
}

IdentityDbContext类源码的更多相关文章

  1. Java集合---Array类源码解析

    Java集合---Array类源码解析              ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...

  2. Cocos2d-X3.0 刨根问底(六)----- 调度器Scheduler类源码分析

    上一章,我们分析Node类的源码,在Node类里面耦合了一个 Scheduler 类的对象,这章我们就来剖析Cocos2d-x的调度器 Scheduler 类的源码,从源码中去了解它的实现与应用方法. ...

  3. List 接口以及实现类和相关类源码分析

    List 接口以及实现类和相关类源码分析 List接口分析 接口描述 用户可以对列表进行随机的读取(get),插入(add),删除(remove),修改(set),也可批量增加(addAll),删除( ...

  4. Thread类源码剖析

    目录 1.引子 2.JVM线程状态 3.Thread常用方法 4.拓展点 一.引子 说来也有些汗颜,搞了几年java,忽然发现竟然没拜读过java.lang.Thread类源码,这次特地拿出来晒一晒. ...

  5. Java并发编程笔记之Unsafe类和LockSupport类源码分析

    一.Unsafe类的源码分析 JDK的rt.jar包中的Unsafe类提供了硬件级别的原子操作,Unsafe里面的方法都是native方法,通过使用JNI的方式来访问本地C++实现库. rt.jar ...

  6. python附录-builtins.py模块str类源码(含str官方文档链接)

    python附录-builtins.py模块str类源码 str官方文档链接:https://docs.python.org/3/library/stdtypes.html#text-sequence ...

  7. Long类源码浅析

    1.Long类和Integer相类似,都是基本类型的包装类,类中的方法大部分都是类似的: 关于Integer类的浅析可以参看:Integer类源码浅析 2.这里主要介绍一下LongCache类,该缓存 ...

  8. java.lang.Void类源码解析_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 在一次源码查看ThreadGroup的时候,看到一段代码,为以下: /* * @throws NullPointerEx ...

  9. org.reflections 接口通过反射获取实现类源码研究

    org.reflections 接口通过反射获取实现类源码研究 版本 org.reflections reflections 0.9.12 Reflections通过扫描classpath,索引元数据 ...

随机推荐

  1. canvas实现画板功能(渐变、动画、阴影...)

    刚刚在博客园落户了,希望能在这认识更多大神,希望能和大家交好朋友. 闲来无事,把以前用canvas写的画板代码改进了一番,用Html5提供的表单标签给其 加了一个选择颜色的功能,因此发现了该标签的一个 ...

  2. python 基础篇第一篇

    本节内容 1.python介绍 2.发展史 3.python2和python3 4.安装 5.简单程序,hello world程序 6.变量 7.用户输入 8.模块初识 9..pyc是什么? 10.数 ...

  3. CSS继承性+层叠性+盒子+浮动

        CSS继承性+层叠性+盒子+浮动 CSS继承性 <style>         div{             color: pink;             font-siz ...

  4. [M]表格中的天正文字转换问题

    若表格中含有天正文字,则不能使用MagicTable直接转换,需要先EXPLODE命令分解(快捷键为x),天正单行文字和天正多行文字都可以使用该命令分解为普通AutoCAD单行文字,分解后即可正常转换 ...

  5. Office下载地址

    文件名cn_office_professional_plus_2016_x86_x64_dvd_6969182.isoSHA1277926A41B472EE38CA0B36ED8F2696356DCC ...

  6. 【类不类二】Python的类变量与实例变量

    在研究类的时候,难免会有很多疑问,C论坛和博客园高手如云(不知道是不是也美女如云), 搜到了这篇博文,是介绍Python的类变量和实例变量的 ! 刚好在下对self.***这种形式的实例变 量不是很理 ...

  7. ucenter无法双向同步setting[allowsynlogin]为0问题解决

    深入探索ucenter各种通信失败问题飞狐ITWeb问题描述:A,B两个应用,A的登录操作等同步到B,而B无法同步到A,即只能从A单向同步到B,AB之间没有实现双向同步以前碰到过没记录,这次记录下来查 ...

  8. SSLv3协议、TLSv1.2协议配置不对导致javax.ws.rs.ProcessingException: java.net.SocketException: Connection reset

    SSl:Secure Sockets Layer 安全套接层 TLS:Transport Layer Security传输层安全 是为网络通信提供安全及数据完整性的一种安全协议.TLS与SSL在传输层 ...

  9. timeit模块 与 time模块,计时的区别

    time  模块,理解容易 import time time_start = time.time() time_end = time.time() time_use = time_end - time ...

  10. 使用webview加载html图片、表单超屏幕问题

    webView加载html代码时,使用webView自带的 scalesPageToFit 可以解决图片所带来的超过屏幕问题:但是,所带来的问题就是文字变小了,怎样让图片边小,并且文字还是原来html ...