ASP.NET MVC 5 identity application user as foreign key

asp.net-identity asp.net-mvc entity-framework

Question

I am aware that Visual Studio 2013 will be formally released tomorrow, and I am hoping that more documentation will be provided, particularly with relation to ASP.NET Identity. I'm hoping that someone will be able to assist me in the interim.

My sole goal is to obtain the UserID of the person who is presently signed in as a foreign key to a database I've dubbed Retailer.

Here is the error message I am receiving in the beginning.

An entity object cannot be referenced by multiple instances of IEntityChangeTracker.

This is my 19-zzz:

public class Retailer
{
    [Key]
    public int RetailerId { get; set; }
    public string BusinessName { get; set; }
    public string PhoneNumber { get; set; }
    public string ManagerName { get; set; }
    public Enums.Industry Industry { get; set; }
    public virtual ApplicationUser UserProfile { get; set; }

}

The table from the aforementioned class was made using Entity Framework CodeFirst as seen here:

CreateTable(
    "dbo.Retailers",
    c => new
        {
            RetailerId = c.Int(nullable: false, identity: true),
            BusinessName = c.String(),
            PhoneNumber = c.String(),
            ManagerName = c.String(),
            Industry = c.Int(nullable: false),
            UserProfile_Id = c.String(maxLength: 128),
        })
    .PrimaryKey(t => t.RetailerId)
    .ForeignKey("dbo.AspNetUsers", t => t.UserProfile_Id)
    .Index(t => t.UserProfile_Id);

I'm trying to add a record to this table in my Controller here:

if (ModelState.IsValid)
{
    var currentUser = await UserManager.FindByIdAsync(User.Identity.GetUserId());
    retailer.UserProfile = currentUser;
    db.Retailers.Add(retailer);
    await db.SaveChangesAsync();
    return RedirectToAction("Index");
}

And here is a portion of the stack trace for complete disclosure:

InvalidOperationException: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.]
   System.Data.Entity.Core.Objects.ObjectContext.VerifyContextForAddOrAttach(IEntityWrapper wrappedEntity) +189
   System.Data.Entity.Core.Objects.ObjectContext.AddSingleObject(EntitySet entitySet, IEntityWrapper wrappedEntity, String argumentName) +126
   System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.AddEntityToObjectStateManager(IEntityWrapper wrappedEntity, Boolean doAttach) +98
   System.Data.Entity.Core.Objects.DataClasses.EntityReference.AddEntityToObjectStateManager(IEntityWrapper wrappedEntity, Boolean doAttach) +65
   System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.AddGraphToObjectStateManager(IEntityWrapper wrappedEntity, Boolean relationshipAlreadyExists, Boolean addRelationshipAsUnchanged, Boolean doAttach) +67
   System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.IncludeEntity(IEntityWrapper wrappedEntity, Boolean addRelationshipAsUnchanged, Boolean doAttach) +341
   System.Data.Entity.Core.Objects.DataClasses.EntityReference`1.Include(Boolean addRelationshipAsUnchanged, Boolean doAttach) +210
   System.Data.Entity.Core.Objects.DataClasses.RelationshipManager.AddRelatedEntitiesToObjectStateManager(Boolean doAttach) +164
   System.Data.Entity.Core.Objects.ObjectContext.AddObject(String entitySetName, Object entity) +520
   System.Data.Entity.Internal.Linq.<>c__DisplayClassd.<Add>b__c() +97
   System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName) +355
   System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity) +200
   System.Data.Entity.DbSet`1.Add(TEntity entity) +130
   ValueCardPremium.Web.Controllers.<Create>d__7.MoveNext() in c:\Users\Valentine\Documents\Visual Studio 2013\Projects\ValueCardProjectPremium\ValueCardPremium.Web\Controllers\RetailerController.cs:70
   System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) +93
   System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +52
   System.Runtime.CompilerServices.TaskAwaiter.GetResult() +21
   lambda_method(Closure , Task ) +64
1
6
3/10/2017 1:24:15 AM

Accepted Answer

The UserManager loads data from the database using its own DbContext. The same dbContext that you used to add a reference to must be used to get the user. the following

var currentUMUser = await UserManager.FindByIdAsync(User.Identity.GetUserId());
var currentUser = db.Users.Find(currentUMUser.UserID);
retailer.UserProfile = currentUser;
db.Retailers.Add(retailer);
await db.SaveChangesAsync();
return RedirectToAction("Index");

Naturally, you will need to utilize whichever technique works best for your models and DbContext to retrieve the user from your database.

13
11/12/2013 6:01:36 PM

Popular Answer

ZZZ_tmp


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow