【问题标题】:ASP.NET MVC5 EF6: Given multiplicity constraints, a corresponding 'User_AppUser_Target' must also in the 'Deleted' state. Repository PatternASP.NET MVC5 EF6:给定多重约束,相应的“User_AppUser_Target”也必须处于“已删除”状态。存储库模式
【发布时间】:2015-03-04 19:25:42
【问题描述】:

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

但是,我已经将旧项目中的 ApplicationUser(AspNetUsers 表)以 1:1 的关系映射到我现有的 User 表(尽可能多的 EF)。这确实是 1:1,这是必要的,因为我的旧表有很多字段。

当我尝试删除用户及其关联的 ApplicationUser 时,我收到以下错误:

“User_AppUser”关联集中的关系位于 “已删除”状态。给定多重约束,对应的 “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) 我有一个外键映射到用户表:

  1. Id nvarchar(128)
  2. 用户名 varchart(256) 等。
  3. UserId int - 映射到用户表:UserId int

这里是删除代码:

[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

但这给出了这个错误:

无法删除该对象,因为它在 对象状态管理器。

我怎样才能让它正确级联删除?

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

    • @RhysStephens - 好吧,您可以让 User 的主键与 ApplicationUser 相同。请参阅weblogs.asp.net/manavi/… 您也可以将其设为 1:Many 并在其上放置唯一索引,使其有效地成为 1:1,但您仍然需要处理具有许多语义的一侧。
    • 对不起,我读过这篇文章,但对我来说没有意义。他们指的是 3 个对象,我只有 2 个。当我 create 新用户时,这种关系有效:var user = new ApplicationUser() { UserName = vm.UserLogin, User = newUser, Email = vm.EmailAddress }; var result = await UserManager.CreateAsync(user, vm.Password);。只是没有删除。
    • @RhysStephens - “UserReviewNotes”是从哪里来的?
    • 对不起。我的意思是:modelBuilder.Entity&lt;User&gt;() .HasOptional(x =&gt; x.AppUser) .WithRequired();
    • @RhysStephens - 您不能只更改映射..您必须更改主键以使用共享键,确保它们是相同的类型,并且依赖类型是非- 生成的密钥..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-05
    • 2016-12-27
    • 2013-07-24
    • 1970-01-01
    • 2018-08-03
    • 2021-07-25
    相关资源
    最近更新 更多