附加类型“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 ...
随机推荐
- QML 开发神奇加成之为网络资源设置本地缓存
QML 开发神奇加成之为网络资源设置本地缓存 直接上码: #include <QNetworkAccessManager> #include <QNetworkDiskCache&g ...
- insertion-sort-list——链表、插入排序、链表插入
Sort a linked list using insertion sort. PS:需要考虑left为head且只有一个数时,此时left->==NULL,若right<left则应更 ...
- 如何卸载centos中自带的Java
首先通过 Java -version 来查看是否已经安装了java 然后通过rpm -qa | grep java 来获得java的版本信息 然后再 用 rpm -e --nodeps [这里依次 ...
- 查询mysql字段名和字段注释
select COLUMN_NAME,column_comment from INFORMATION_SCHEMA.Columns where table_name='表名' and table_sc ...
- C#实现模拟登录百度并发送私信
首先获取Token,根据Token获取PubliKey,使用RSA加密POST数据 private Regex _regex = new Regex(@"\{.*\}", Rege ...
- 标准C头文件
ISO C标准定义的头文件: POSIX标准定义的必须的头文件: POSIX标准定义的XSI可选头文件: POSIX标准定义的可选头文件:
- 每天一个JavaScript实例-apply和call的使用方法
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- java的自定义异常类
编写自定义异常类的模式 编写自定义异常类实际上是继承一个Exception标准异常类,用新定义的异常处理信息覆盖原有信息的过程.常用的编写自定义异常类的模式如下: public classCustom ...
- 0 lrwxrwxrwx. 1 root root 13 Nov 20 12:44 scala -> scala-2.12.4
符号链接的文件属性相同,真正的权限属性由符号链接所指向的实际文件决定.
- 如何去除Office Excel的密码保护?
企图更改Excel文件内容,然而却弹出如下提示: 根据提示,我尝试解除保护表,却要求输入密码: 这就尴尬了=_=密码不是我设定的 问了度娘,找到了解决方案 将Excel文件扩展名更改为rar, 使用压 ...