IdentityDbContext类源码
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类源码的更多相关文章
- Java集合---Array类源码解析
Java集合---Array类源码解析 ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...
- Cocos2d-X3.0 刨根问底(六)----- 调度器Scheduler类源码分析
上一章,我们分析Node类的源码,在Node类里面耦合了一个 Scheduler 类的对象,这章我们就来剖析Cocos2d-x的调度器 Scheduler 类的源码,从源码中去了解它的实现与应用方法. ...
- List 接口以及实现类和相关类源码分析
List 接口以及实现类和相关类源码分析 List接口分析 接口描述 用户可以对列表进行随机的读取(get),插入(add),删除(remove),修改(set),也可批量增加(addAll),删除( ...
- Thread类源码剖析
目录 1.引子 2.JVM线程状态 3.Thread常用方法 4.拓展点 一.引子 说来也有些汗颜,搞了几年java,忽然发现竟然没拜读过java.lang.Thread类源码,这次特地拿出来晒一晒. ...
- Java并发编程笔记之Unsafe类和LockSupport类源码分析
一.Unsafe类的源码分析 JDK的rt.jar包中的Unsafe类提供了硬件级别的原子操作,Unsafe里面的方法都是native方法,通过使用JNI的方式来访问本地C++实现库. rt.jar ...
- python附录-builtins.py模块str类源码(含str官方文档链接)
python附录-builtins.py模块str类源码 str官方文档链接:https://docs.python.org/3/library/stdtypes.html#text-sequence ...
- Long类源码浅析
1.Long类和Integer相类似,都是基本类型的包装类,类中的方法大部分都是类似的: 关于Integer类的浅析可以参看:Integer类源码浅析 2.这里主要介绍一下LongCache类,该缓存 ...
- java.lang.Void类源码解析_java - JAVA
文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 在一次源码查看ThreadGroup的时候,看到一段代码,为以下: /* * @throws NullPointerEx ...
- org.reflections 接口通过反射获取实现类源码研究
org.reflections 接口通过反射获取实现类源码研究 版本 org.reflections reflections 0.9.12 Reflections通过扫描classpath,索引元数据 ...
随机推荐
- (转)GBDT迭代决策树理解
在网上看到一篇对从代码层面理解gbdt比较好的文章,转载记录一下: GBDT(Gradient Boosting Decision Tree) 又叫 MART(Multiple Additive Re ...
- mysql报错1024-can't get hostname for your address
前一段时间mysql用的好好的,突然一天,mysql启动后,在使用navicat连接数据库的时候 报错1024-can't get hostname for your address 这里我是这样解决 ...
- 原图旋转/缩放 然后画布画图 ImageProcessor
//旋转 byte[] photoBytes = File.ReadAllBytes(HttpContext.Current.Server.MapPath(diyInfo.ImageUrl)); Im ...
- Zookeeper,Kafka,Spark关系
Kafka中ZooKeeper的用途 正如ZooKeeper用于分布式系统的协调和促进,Kafka使用ZooKeeper也是基于相同的原因.ZooKeeper用于管理.协调Kafka代理.每个Kafk ...
- UIColor,CGColor,CIColor三者间的区别和联系
一.UIColor UIColor是UIKit中存储颜色信息的一个重要的类,一个UIColor对象包含了颜色和透明度的值,它的颜色空间已经针对IOS进行了优化.UIColor包含了一些类方法用于创建一 ...
- Scala Singleton对象
Scala Object: scala没有静态的修饰符,例如Java中的static.但是Scala提供了Object类型,object下的成员都是静态的,比较像Java的静态类.不同在于Scala的 ...
- 【IE6的疯狂之六】li在IE中底部3像素的BUG(增加浮动解决问题)
今天开发项目中碰到一个li在IE中的BUG,先来看设计原型(如图:) 两个红色中间是<li>1px的底边框: 我写的代码如下: ============================== ...
- 修改LibreOffice Draw中定义的样式名称
目前我使用的是LibreOffice 4.2.4.2.经过以往的测试和使用经验,这是诸多版本中较为稳定和bug相对较少的.今天无意中发现该版本的LibreOffice Draw存在一个问题:样式名称修 ...
- sendUserActionEvent() mView== null after clicking on button
this is not a problem related to your code, but related to S4 android version. Same question has bee ...
- mysql最大连接数问题
进入mysql系统就, 查询最大连接数:show variables like 'max_connections'; 修改最大连接数:set global max_connections=1000;