附加类型“UniversalReviewSystem.Models.ApplicationUser”的实体失败,因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值
在使用asp.net Identity2 的 UserManager RoleManager 时,同时还有其他仓储类型接口,能实现用户扩展信息的修改,用户注册没有问题。当修改用户信息时,出现了如下异常。


public class AccountController : Controller
{
private IDepartmentService _departmentService;
public AccountController(IDepartmentService departmentService)
{
_departmentService = departmentService;
}
private ApplicationUserManager _userManager;
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, ApplicationRoleManager roleManager, IDepartmentService departmentService)
{
UserManager = userManager;
SignInManager = signInManager;
RoleManager = roleManager;
_departmentService = departmentService;
}
public ApplicationUserManager UserManager
{
get
{
//return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
return _userManager ?? new ApplicationUserManager(new UserStore<ApplicationUser>(ContextFactory.GetCurrentContext()));
}
private set
{
_userManager = value;
}
}
private ApplicationRoleManager _roleManager;
public ApplicationRoleManager RoleManager
{
get
{
//return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
return _roleManager ?? new ApplicationRoleManager(new RoleStore<ApplicationRole>(ContextFactory.GetCurrentContext()));
}
set
{
_roleManager = value;
}
}
///创建用户不会产生异常。
// GET: /Account/Create
//[Authorize(Roles="SuperAdmin")]
public async Task<ActionResult> Create() //由原Register 方法修改成Create方法
{
ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "RoleRealName");
ViewBag.DepartmentID = new SelectList(await _departmentService.FindAll().ToListAsync(), "DepartmentID", "DepartmentName");
// RegisterViewModel registerViewModel = new RegisterViewModel(); //此处可以初始化一个实例,为视图返回一个一些默认值的对象。
return View();
}
//
// POST: /Account/Create
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(RegisterViewModel model, params string[] selectedRoles)//可变数组参数。 模型绑定自动完成,给selectedRoles 可变参数数组传入参数。
{
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.UserName, Email = model.Email,RealName=model.RealName, Gender=model.Gender,Birthday=model.Birthday,ProfessionalTitle=model.ProfessionalTitle,InCollege=model.InCollege,DepartmentID=model.DepartmentID};
var userResult = await UserManager.CreateAsync(user, model.Password);//添加用户//在数据库中创建了这个用户,那么就生成了UserID 了。
//给用户添加角色
if (userResult.Succeeded)
{
// await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
// 有关如何启用帐户确认和密码重置的详细信息,请访问 http://go.microsoft.com/fwlink/?LinkID=320771
// 发送包含此链接的电子邮件
// string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
// var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
// await UserManager.SendEmailAsync(user.Id, "确认你的帐户", "请通过单击 <a href=\"" + callbackUrl + "\">這裏</a>来确认你的帐户");
if (selectedRoles != null)
{
var result = await UserManager.AddToRolesAsync(user.Id, selectedRoles);
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "RoleRealName");
ViewBag.DepartmentID = new SelectList(await _departmentService.FindAll().ToListAsync(), "DepartmentID", "DepartmentName");
return View(model);
}
}
}
else
{
ModelState.AddModelError("",userResult.Errors.First());
ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "RoleRealName");
ViewBag.DepartmentID = new SelectList(await _departmentService.FindAll().ToListAsync(), "DepartmentID", "DepartmentName");
return View(model);
}
return RedirectToAction("Index"); //如果用户添加成功,角色创建成功就返回Index.2、如果用户添加成功,但没有选中角色,也返回Index.
}
// 如果我们进行到这一步时某个地方出错,则重新显示表单
ViewBag.RoleID = new SelectList(await RoleManager.Roles.ToListAsync(), "Name", "RoleRealName");
ViewBag.DepartmentID = new SelectList(await _departmentService.FindAll().ToListAsync(), "DepartmentID", "DepartmentName");
return View(model);
}
//Get Account/EditUser 系统管理员修改其他人的信息
public async Task<ActionResult> EditUser(string Id)
{
if (string.IsNullOrEmpty(Id))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest); //HttpStatusCode.BadRequest 在System.Net 命名空间下面。
}
var _user = await UserManager.FindByIdAsync(Id);
if (_user == null)
{
return HttpNotFound();
}
var userRoles = await UserManager.GetRolesAsync(_user.Id);
var editUser = new EditUserViewModel
{
Id = _user.Id,
UserName = _user.UserName,
Email = _user.Email,
RealName = _user.RealName,
Gender = _user.Gender,
Birthday = _user.Birthday,
InCollege = _user.InCollege,
ProfessionalTitle = _user.ProfessionalTitle,
RolesList = RoleManager.Roles.ToList().Select(x => new SelectListItem() //建立一个投影,如果角色中包含当前用户的角色,就选中此角色。
{
Text =x.RoleRealName + "-"+ x.Description,
Value =x.Name,
Selected =userRoles.Contains(x.Name)
})
};
ViewBag.DepartmentList = new SelectList(_departmentService.FindAll().OrderBy(d => d.DepartmentName), "DepartmentID", "DepartmentName",_user.DepartmentID);
return View(editUser);
}
/// <summary>
/// 管理员编辑其他用户的信息
/// </summary>
/// <param name="user"></param>
/// <param name="selectedRoles"></param>
/// <returns></returns>
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> EditUser([Bind(Include = "Id,UserName,Email,RealName,Gender,Birthday,DepartmentID,InCollege,ProfessionalTitle")] EditUserViewModel user, params string[] selectedRoles)
{
if (ModelState.IsValid)
{
//var _user = await UserManager.Users.AsNoTracking().SingleOrDefaultAsync(x => x.Id == user.Id);
var _user = await UserManager.FindByIdAsync(user.Id);
if (_user == null)
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
_user.UserName = user.UserName;
_user.Email = user.Email;
_user.RealName = user.RealName;
_user.Gender = user.Gender;
_user.Birthday =user.Birthday;
_user.DepartmentID = user.DepartmentID;
_user.InCollege = user.InCollege;
_user.ProfessionalTitle = user.ProfessionalTitle;
var userRoles = await UserManager.GetRolesAsync(_user.Id);
selectedRoles = selectedRoles ?? new string[] { };
var result = await UserManager.AddToRolesAsync(user.Id, selectedRoles.Except(userRoles).ToArray<string>());
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
ViewBag.DepartmentList = new SelectList(_departmentService.FindAll().OrderBy(d => d.DepartmentName), "DepartmentID", "DepartmentName", _user.DepartmentID);
return View(user);
}
result = await UserManager.RemoveFromRolesAsync(user.Id, userRoles.Except(selectedRoles).ToArray<string>());
if (!result.Succeeded)
{
ModelState.AddModelError("", result.Errors.First());
ViewBag.DepartmentList = new SelectList(_departmentService.FindAll().OrderBy(d => d.DepartmentName), "DepartmentID", "DepartmentName", _user.DepartmentID);
return View(user);
}
await UserManager.UpdateAsync(_user); //异步更新用户信息 执行到此处出现 了 “附加类型“UniversalReviewSystem.Models.ApplicationUser”的实体失败,因为相同类型的其他实体已具有相同的主键值。”的异常。
return RedirectToAction("Index");
}
ModelState.AddModelError("", "绑定失败");
ViewBag.DepartmentList = new SelectList(_departmentService.FindAll().OrderBy(d => d.DepartmentName), "DepartmentID", "DepartmentName", user.DepartmentID);
return View(user);
}
另外,还定义一个静态的工厂类,用于产生数据库上下文。
public static class ContextFactory //静态类不能被实例化,只能有静态成员。
{
public static UniversalReviewSystemDbContext GetCurrentContext()
{
UniversalReviewSystemDbContext context = CallContext.GetData("UniversalReviewSystemContext") as UniversalReviewSystemDbContext;
if (context == null)
{
context = new UniversalReviewSystemDbContext();
CallContext.SetData("UniversalReviewSystemContext", context);
}
return context;
}
}
出现异常的原因,可能是UserManager、RoleManager使用了不同的数据库上下文。 ContextFactory 使用CallContext 并不能保证数据库上下文一致。 把数据库上下文更改一下就行了。但同时增加了 userManager 用户的验证逻辑。
在UserManager 和RoleManager 的属性中,
恢复默认的
get
{
return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
}
get
{
return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>();
}
也可以在控制器中 为UserManager,RoleManager 使用同一数据库上下文对象。
UniversalReviewSystemDbContext db =ContextFactory.GetCurrentContext();
return _userManager ?? new ApplicationUserManager(new UserStore<ApplicationUser>(db));
return _roleManager ?? new ApplicationRoleManager(new RoleStore<ApplicationRole>(ContextFactory.GetCurrentContext()));

附加类型“UniversalReviewSystem.Models.ApplicationUser”的实体失败,因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值的更多相关文章
- 关于Entity Framework更新的几种方式以及可能遇到的问题(附加类型“Model”的实体失败,因为相同类型的其他实体已具有相同的主键值)在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为
在日常使用Entity Framework中,数据更新通常会用到.下面就简单封装了一个DBContext类 public partial class EFContext<T> : DbCo ...
- 附加类型的实体失败,因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 时如果图形中的任何实体具有冲突键值
var list= DAL.LoadEntities(x => x.OrderCode == orderCode).AsNoTracking().ToList().FirstOrDefault( ...
- 因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 。。。
因为相同类型的其他实体已具有相同的主键值.在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified&quo ...
- 错误:因为相同类型的其他实体已具有相同的主键值。在使用 "Attach" 方法或者将实体的状态设置为 "Unchanged" 或 "Modified" 解决方法
在更新一个实体类的时候可能会有预先有一次查询或者其它操作,我们这样用目的是为了与提交的数据做一个比较之类的东西,如果先查询再对此类进行SaveChanges就会出错. 我们只要用AsNoTrackin ...
- 《Entity Framework 6 Recipes》中文翻译系列 (41) ------ 第七章 使用对象服务之标识关系中使用依赖实体与异步查询保存
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 7-7 标识关系中使用依赖实体 问题 你想在标识关系中插入,更新和删除一个依赖实体 ...
- 为什么分布式数据库中不使用uuid作为主键?
分布式数据库当然也有主键的需求,但是为什么不直接使用uuid作为主键呢?作为曾经被这个问题困惑过的人,试着回答一下 1. UUID生成速率低下 Java的UUID依赖于SecureRandom.nex ...
- 基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型、函数名、参数个数、参数类型及参数的先后顺序,都必须与基类中的原型完全相同 but------> 可以返回派生类对象的引用或指针
您查询的关键词是:c++primer习题15.25 以下是该网页在北京时间 2016年07月15日 02:57:08 的快照: 如果打开速度慢,可以尝试快速版:如果想更新或删除快照,可以投诉快照. ...
- 解决:oracle+myBatis ResultMap 类型为 map 时返回结果中存在 timestamp 时使用 jackson 转 json 报错
前言:最近在做一个通用查询单表的组件,所以 sql 的写法就是 select *,然后 resultType="map" ,然后使用 jackson @ResponseBody 返 ...
- 在动态sql的使用where时,if标签判断中,如果实体类中的某一个属性是String类型,那么就可以这样来判断连接语句:
在动态sql的使用where时,if标签判断中,如果实体类中的某一个属性是String类型,那么就可以这样来判断连接语句: 如果是String类型的字符串进行判空的时候: <if test=&q ...
随机推荐
- 入手Arduino Yun,配合Blynk搞一波事情
前言 原创文章,转载引用务必注明链接. 最近在闲鱼上与别人用RPi2尸体+好的BBB换了个Arduino Yun,等了几天赶在节前收到了.出奇的轻巧,产地台湾,官方正品做工就是精细~采用5v Micr ...
- 基于社交网络的情绪化分析IV
基于社交网络的情绪化分析IV By 白熊花田(http://blog.csdn.net/whiterbear) 转载需注明出处,谢谢. 前面进行了微博数据的抓取,简单的处理,类似度分析.后面两篇进行学 ...
- POJ 3928 Ping pong 树状数组模板题
開始用瓜神说的方法撸了一发线段树.早上没事闲的看了一下树状数组的方法,于是又写了一发树状数组 树状数组: #include <cstdio> #include <cstring> ...
- html5 式程序员表白
html5 式程序员表白 王海庆 于 星期三, 04/06/2014 - 00:44 提交 今天是个好日子,2014年5月20日,表白的最佳时机,虽说孩子已经四岁.结婚已经五年.可是也不能够偷懒.于是 ...
- sql注入攻防 以php+mysql为例
随着Web应用的高速发展和技术的不断成熟,对Web开发相关职位的需求量也越来越大,越来越多的人加入了Web开发的行列.但是由于程序员的水平参差不齐或是安全意识太低,很多程序员在编写代码时仅考虑了功能上 ...
- 【前端JS】radio 可单选可点击取消选中
普通情况下 radio 单选框仅仅能实现多选一的效果,可是一旦选择当中一个后,这个单选框就不可点击取消其选中状态了.这样的功能在某些业务环境下并不适用.有时我们既须要单选框的多选一效果.也须要复选框的 ...
- 开源项目:单行日历(CalendarView)
http://www.cnblogs.com/warnier-zhang/p/4750525.html CalendarView.zip
- 我为什么不喜欢 CoreData
我为什么不喜欢 CoreData 我一直不喜欢 Core Data,以前不太敢明目张胆地这么表达,现在收集到越来越多相关的信息,所以给大家分享一下,我为什么不喜欢 Core Data. Core ...
- 赵雅智_SimpleCursorAdapter
项目步骤 声明listView控件并获取显示的视图 获取显示的数据 设置显示的adapter 注冊点击事件 详细案例 实现效果: watermark/2/text/aHR0cDovL2Jsb2cuY3 ...
- VUE 之 路由 VueRouter
1.VueRouter的安装 1.1.https://unpkg.com/vue-router/dist/vue-router.js下载安装. 1.2.<script src="./s ...