问题
I am trying to delete an item from my AspNetRoles table that has been extended like this:
public class AspApplicationRoles : IdentityRole
{
public AspApplicationRoles() : base() { }
public AspApplicationRoles(String Name) : base(Name) { }
[Required]
public String ApplicationId { get; set; }
public AspNetApplications Application { get; set; }
}
This is the way I am trying to delete it. I use the Get function with an Input of its ID to get the item and try to delete it. However, I get this error at manager.Delete: {"The object cannot be deleted because it was not found in the ObjectStateManager."}
public RolesDetailsViewModel Get(String Input)
{
AspApplicationRoles data = new AspApplicationRoles() ;
RolesDetailsViewModel rdvm = new RolesDetailsViewModel();
try
{
data = dbContext.AspApplicationRoles.Single(r => r.Id == Input);
rdvm = new RolesDetailsViewModel
{
ApplicationId = data.ApplicationId,
Id = data.Id,
RoleName = data.Name
};
}
catch (Exception e)
{
logger.Error(e, AspNetEventLogs.NotFound);
}
return rdvm;
}
public void Delete(String Input)
{
var store = new RoleStore<AspApplicationRoles>(dbContext);
var manager = new RoleManager<AspApplicationRoles>(store);
try
{
var role = Get(Input);
var r = new AspApplicationRoles
{
Id = role.Id,
ApplicationId = role.ApplicationId,
Name = role.RoleName
};
manager.Delete(r);
logger.Info(AspNetEventLogs.Delete + " Role: " + role.RoleName);
}
catch (Exception e)
{
logger.Error(e, "Failed to delete Role");
}
}
I have tried looking around for a solution but if I use the dbContext.Attach function, I get another error that states that there are 2 objects with the same primary key?
Hope someone can see this. Thank you.
EDIT:
My code works when I change my Delete function to this:
public void Delete(String Input)
{
var store = new RoleStore<AspApplicationRoles>(dbContext);
var manager = new RoleManager<AspApplicationRoles>(store);
try
{
var role = dbContext.AspApplicationRoles.Single(r => r.Id == Input);
manager.Delete(role);
logger.Info(AspNetEventLogs.Delete + " Role: " + role.Name);
}
catch (Exception e)
{
logger.Error(e, "Failed to delete Role");
}
}
However, is it possible to reuse my Get function instead of calling the LINQ function each time?
回答1:
RoleManager.Delete calls RoleStore.Delete which finally call DbSet<Role>.Remove(role). As it's already mentioned in DbSet<T>.Remove(T), the that you pass to the entity must exist in the context in some other state before this method is called.
Obviously the role instance which you create using new Role() doesn't exists in the context. So the following line of code will throw an exception:
var r = new Role(){ ... };
manager.Delete(r); // ← throws exception
Above description also describes why your edited code works, because you load a role into context, then try to delete that attached (tracked) role.
If you would like to reuse the Get method which you create, the method should return Role or have a reference to the Role in the return value. Then that reference (which has been attached to EF context) can be easily deleted by manager, because it's been tracked.
来源:https://stackoverflow.com/questions/52039445/the-object-cannot-be-deleted-because-it-was-not-found-in-the-objectstatemanager