ASP.NET MVC5 EF6:给定多重约束,相应的' User_AppUser_Target'还必须在“删除”中删除。州。存储库模式

时间:2015-01-07 02:00:41

标签: c# asp.net-mvc-5 entity-framework-6 repository-pattern asp.net-identity-2

我有一个使用Identity 2和Entity Framework 6的MVC5项目和存储库模式,即重新开发旧的经典asp系统。 我使用Identity 1启动了项目,之后在v2中他们介绍了ApplicationUser主键可以是任何东西,而不仅仅是GUID。

但是,我已经将ApplicationUser(AspNetUsers表)从旧项目映射到我现有的User表,作为1:1关系(与EF一样多)。它真的是1:1,这是必要的,因为我的旧桌子有很多领域。

当我尝试删除用户,并且它与ApplicationUser相关联时,我收到以下错误:

  

来自'User_AppUser'AssociationSet的关系在   '删除'状态。给定多重约束,相应的   'User_AppUser_Target'也必须处于'已删除'状态。

以下是应用用户:

    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {                
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);             
            return userIdentity;
        }

        public virtual User User { get; set; }
    }

以下是用户

public class User : BaseModel
{        
    // The new identity system has a Guid as Id that is different to the UserId, So on the AspNetUser table there is new UserId field mapped.
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }    
    public virtual ApplicationUser AppUser { get; set; }      
    public string UserLogin { get { return AppUser.UserName; } }
    public string UserPass { get { return AppUser.PasswordHash; } }
    public string EmailAddress { get { return AppUser.Email; } }

    //.....ETC ....//
}

以下是映射:

modelBuilder.Entity<User>()                
            .HasRequired(e => e.AppUser)                
            .WithRequiredPrincipal(e => e.User)
            .Map(c=>c.MapKey("UserId"))
            .WillCascadeOnDelete(true);

这是applicationUser表(AspNetUser) 我有一个外键映射到User表:

  1. Id nvarchar(128)
  2. UserName varchart(256)等..
  3. UserId int - 映射到用户表:UserId int
  4. 以下是删除代码:

    [HttpPost, ValidateAntiForgeryToken]
    public async Task<ActionResult> Delete([Bind(Include="Id")] UserSaveViewModel viewModel)
    {            
        ApplicationUser appUser = UserManager.FindById(viewModel.Id);                        
        await UserManager.DeleteAsync(appUser);                        
        return RedirectToAction("Index", new { isUserDeleted = true });
    }
    

    我也试过这个而不是UserManager.DeleteAsync()

    var user = appUser.User;
    await _repository.DeleteAsync<User>(user); //using the repository pattern
    

    但是这给出了这个错误:

      

    无法删除该对象,因为在该对象中找不到该对象   ObjectStateManager。

    如何正确地级联删除?

1 个答案:

答案 0 :(得分:3)

您不能以这种方式映射1:1关系。 EF支持1:1映射的唯一方法是使用共享主键,这意味着两个表必须具有相同的密钥,并且一个必须是另一个的外键。

很不幸,但是从EF不支持唯一约束的时候起,它就是一种保留,如果没有使用唯一约束,就不能在没有共享主键的情况下进行1:1映射。当EF 6.1添加了唯一索引支持时,内部逻辑从未更新为完全支持1:1场景。