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);
}
}
}

上面的代码出自:

https://www.symbolsource.org/MyGet/Metadata/aspnetwebstacknightly/Project/Microsoft.AspNet.Identity.EntityFramework/2.0.0-rtm-140221/Release/Default/Microsoft.AspNet.Identity.EntityFramework/Microsoft.AspNet.Identity.EntityFramework/IdentityDbContext.cs?ImageName=Microsoft.AspNet.Identity.EntityFramework

想查看Microsoft.AspNet.Identity.EntityFramework.dll中IdentityDbContext的源码,却发现Github上Identity的代码和实际调用的dll里面的结构不一致。

找到如上代码,留文备用。

Microsoft.AspNet.Identity.EntityFramework/IdentityDbContext.cs的更多相关文章

  1. Asp.net Identity 系列之 怎样修改Microsoft.AspNet.Identity.EntityFramework.IdentityUser 的 Id 字段的数据类型

    这篇博客我们来学习如何将AspNetUsers 表的Id 字段 的类型由nvarchar(128) 改为Int 并且子增长 1.为什么要修改 如果你运行过 Asp.net mvc 示例项目,你好会发现 ...

  2. 从Microsoft.AspNet.Identity看微软推荐的一种MVC的分层架构

    Microsoft.AspNet.Identity简介 Microsoft.AspNet.Identity是微软在MVC 5.0中新引入的一种membership框架,和之前ASP.NET传统的mem ...

  3. Microsoft.AspNet.Identity 自定义使用现有的表—登录实现

    Microsoft.AspNet.Identity是微软新引入的一种membership框架,也是微软Owin标准的一个实现.Microsoft.AspNet.Identity.EntityFrame ...

  4. Microsoft.AspNet.Identity 的简单使用

    要完成一个简单的注册,登陆,至少需要实现Identity中的3个接口 IUser IUserStore<TUser> : IDisposable where TUser : IUser I ...

  5. MVC5中 在更新 Microsoft.Aspnet.Identity 后编译器错误

    环境:vs2013预览版chs,我试着创建vb.net web应用,从对话框中选择MVC和WebAPI.编译ok了.通过NuGet管理器更新了Microsoft.Aspnet.Identity.Cor ...

  6. Microsoft.AspNet.Identity 自定义使用现有的表—登录实现,aspnet.identity

    Microsoft.AspNet.Identity是微软新引入的一种membership框架,也是微软Owin标准的一个实现.Microsoft.AspNet.Identity.EntityFrame ...

  7. 跟Microsoft.AspNet.Identity学习哈希加盐法

    什么是哈希加盐法? 废话少说:对于MD5这种加密算法,同样的密码每次加密后得到的密文是一样的,所以黑客可以利用已知的密码库(彩虹库)对目标数据库密文进行对比进行攻击. 怎样解决:哈希加盐法,以下是网上 ...

  8. Microsoft.AspNet.Identity: UserID用整型数据表示, 而不是GUID

    第一篇:  这个好像不太好 http://stackoverflow.com/questions/19553424/how-to-change-type-of-id-in-microsoft-aspn ...

  9. Microsoft.AspNet.Identity 重置密码

    重置密码:先生成重置密码的Token,然后调用ResetPassword方法重置密码,密码要符合规则.. ApplicationUserManager UserManager => _userM ...

随机推荐

  1. Yii2 使用 faker 生成假数据(转)

    测试过程中有时候需要生成大量的假数据,faker 是一个生成假数据的类库,可以生成姓名,电话,IP地址,密码,ISBN等等你能想到的或者你想不到的各种类型的假数据. Yii2.0已经集成该类库,不用再 ...

  2. 幽灵漏洞(Ghost gethost)

    幽灵漏斗简介: 编号CVE-2015-0235的GHOST(幽灵)漏洞是Qualys研究员发现的一个Linux服务上非常严重的安全漏洞,可以被利用来远程代码执行及本地权限提升. 漏洞简要描述 该漏洞存 ...

  3. “TableDetails”中列“IsPrimaryKey”的值为DBNull. Mysql EntityFramework

                                                                                Entity Framework连接MySQL时 ...

  4. MSSQL分组取后每一组的最新一条记录

    数据库中二张表,用户表和奖金记录表,奖金记录表中一个用户有多条信息,有一个生效时间,现在要查询: 奖金生效时间在三天前,每个用户取最新一条奖金记录,且用户末锁定 以前用的方法是直接写在C#代码中的: ...

  5. pandas数组(pandas Series)-(4)NaN的处理

    上一篇pandas数组(pandas Series)-(3)向量化运算里说到,将两个 pandas Series 进行向量化运算的时候,如果某个 key 索引只在其中一个 Series 里出现,计算的 ...

  6. [Windows Azure] Create a Virtual Network in Windows Azure

    Create a Virtual Network in Windows Azure This tutorial walks you through the steps to create a basi ...

  7. 每日英语:Are Smartphones Turning Us Into Bad Samaritans?

    In late September, on a crowded commuter train in San Francisco, a man shot and killed 20-year-old s ...

  8. JavaScript 模块化简述

    JavaScript 模块化简述 前言 关于模块化,最直接的表现就是我们写的 require 和 import 关键字,如果查阅相关资料,就一定会遇到 CommonJS .CMD AMD 这些名词,以 ...

  9. hive的UDF读取配置文件

    hive的UDF读取配置文件 实现步骤 在读取配置文件的写为./file_name,然后在添加UDF的时候把配置文件也加入资源就好了: add jar xxx.jar; add file file_n ...

  10. One-hot 编码/TF-IDF 值来提取特征,LAD/梯度下降法(Gradient Descent),Sigmoid

    1. 多值无序类数据的特征提取: 多值无序类问题(One-hot 编码)把“耐克”编码为[0,1,0],其中“1”代表了“耐克”的中 间位置,而且是唯一标识.同理我们可以把“中国”标识为[1,0],把 ...