我使用EF6.1开展MVC 5项目。作为初学者,我尝试保留MVC 5模板生成的代码,以便使用AccountController的默认身份验证系统。 但是,我必须添加一些类,如下面的“User.cs”,所以我正在使用实体框架数据模型。
public partial class User
{
public User()
{
this.Logs= new HashSet<Log>();
}
public int IdUser { get; set; }
public string AspNetUsersId { get; set; } //References to AspNetUsers.Id
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Job{ get; set; }
public virtual ICollection<Log> Logs { get; set; }
}
所以,我有两个背景:
public partial class MyEFDataModelContainer : DbContext
{
public MyEFDataModelContainer ()
: base("name=MyEFDataModelContainer")
{
}
public DbSet<User> Users { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
所以,我的场景是我需要创建一个AspNetUsers,然后在这个AspNetUsers中添加一个AspNetRoles,然后创建一个User。我们假设AspNetUsers创建和AspNetRoles工作,但如果用户创建失败,我该如何回滚AspNetUsers和AspNetRoles?
我可以用这两个上下文创建一个事务吗?
不幸的是,我还需要调用WCF webservices来执行此任务?我该怎么办?
致以最诚挚的问候,
更新
我的合并上下文:
public partial class User: IdentityUser { }
public partial class MyEFDataModelContainer : IdentityDbContext<User>
{
public MyEFDataModelContainer() : base("name=MyEFDataModelContainer")
{ }
}
我的AccountController.cs:
public class AccountController : Controller
{
public AccountController()
{
UserManager =new UserManager<User>(new UserStore<User>(new MyEFDataModelContainer()))
}
public UserManager<User> UserManager {get;set;}
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
var user = new USER() { UserName = model.UserName, Email = model.Email, PhoneNumber = model.Phone };
var result = await UserManager.CreateAsync(user, model.Password);
var role = await UserManager.AddToRoleAsync(user.Id, "Membre");
if (result.Succeeded)
{
using (UserBusiness business = new UserBusiness())
{
var userResult = business.AddUser(model.FirstName, model.LastName, user.Id);
}
await SignInAsync(user, isPersistent: false);
return RedirectToAction("Index", "Home");
}
else
{
AddErrors(result);
}
}
return View(model);
}
}
我的Web.config:
<connectionStrings>
<add name="MyEFDataModelContainer" connectionString="metadata=res://*/MyEFDataModel.csdl|res://*/MyEFDataModel.ssdl|res://*/MyEFDataModel.msl;provider=System.Data.SqlClient;provider connection string="data source=localhost;initial catalog=DB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
但是现在,我有错误 LINQ to Entities不支持指定的类型成员'UserName'。仅支持初始值设定项,实体成员和实体导航属性。位于以下行:
var result = await UserManager.CreateAsync(user, model.Password);
答案 0 :(得分:1)
所以,我的第一个问题是,为什么你需要两个背景?有没有理由说aspnet表必须与业务表分开?
你可以这样做:
public partial class MyEFDataModelContainer : IdentityDbContext<User>
{
public MyEFDataModelContainer ()
: base("name=MyEFDataModelContainer")
{
}
public DbSet<User> Users { get; set; }
}
确保您的自定义User类继承自IdentityUser。
public partial class User : IdentityUser
{
public User()
{
this.Logs= new HashSet<Log>();
}
public int IdUser { get; set; }
public string AspNetUsersId { get; set; } //References to AspNetUsers.Id
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Job{ get; set; }
public virtual ICollection<Log> Logs { get; set; }
}
然后,将AccountController更改为此连接字符串。这样一切都在同一个数据库中。
public class AccountController : Controller
{
public AccountController()
: this(new UserManager<User>(
new UserStore<User>(new MyEFDataModelContainer())))
{
}
}
虽然,为了回答你的问题,是的,你可以在事务中包含对两个上下文的访问。然而,根据我的经验,你必须处理MSDTC,这有时令人沮丧。