MVC 5 IdentityDbContext and DbContext Operations

I am working on an MVC 5 project with EF6.1. As a newbie, I am trying to save the code generated by the MVC 5 template in order to use the default authentication system with AccountController. However, I had to add some classes, such as "User.cs", as shown below, so I use the Entity Framework data model.

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

So, I have two contexts:

 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") { } } 

So my scenario is that I need to create AspNetUsers, and then add AspNetRoles to these AspNetUsers, and then create the user. We assume that creating AspNetUsers and AspNetRoles works, but if user creation failed, how can I roll back AspNetUsers and AspNetRoles?

Is it possible to create a transaction with these two contexts?

Unfortunately, I also need to call WCF web services to complete this task? What can I do?

Yours faithfully,

Update

My combined contexts:

 public partial class User: IdentityUser { } public partial class MyEFDataModelContainer : IdentityDbContext<User> { public MyEFDataModelContainer() : base("name=MyEFDataModelContainer") { } } 

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

My web.config:

 <connectionStrings> <add name="MyEFDataModelContainer" connectionString="metadata=res://*/MyEFDataModel.csdl|res://*/MyEFDataModel.ssdl|res://*/MyEFDataModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=localhost;initial catalog=DB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" /> </connectionStrings> 

But now I have an error. The specified member of type 'UserName' is not supported in LINQ to Entities. Only initializers, entities, and entity navigation properties are supported. in the next line:

 var result = await UserManager.CreateAsync(user, model.Password); 
+1
source share
1 answer

So, my first question is: why do you need two contexts? Is there a reason why aspnet tables should be separated from business tables?

Could you do something like:

 public partial class MyEFDataModelContainer : IdentityDbContext<User> { public MyEFDataModelContainer () : base("name=MyEFDataModelContainer") { } public DbSet<User> Users { get; set; } } 

Verify that the user class inherits from 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; } } 

Then change your AccountController to this connection string. Thus, everything is in one database.

 public class AccountController : Controller { public AccountController() : this(new UserManager<User>( new UserStore<User>(new MyEFDataModelContainer()))) { } } 

Although, to answer your question, yes, you can wrap access to two contexts within a transaction. However, you will have to deal with MSDTC, which in my experience can sometimes be frustrating.

+1
source

Source: https://habr.com/ru/post/1243456/


All Articles