从ApplicationUser(IdentityUser)

时间:2016-12-24 14:23:21

标签: c# asp.net .net asp.net-mvc entity-framework

我在ASP .NET Identity中有两个继承自ApplicationUser的类, 课程如下:

这是我的ApplicationUser类

public class ApplicationUser : IdentityUser
{
    public string Name { get; set; }

    public string Surname { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
}

继承它的两个类:

public class User : ApplicationUser
{
    public virtual ICollection<Repair> Repairs { get; set; }

    public virtual ICollection<Vehicle> Vehicles { get; set; }
}

public class Repairer : ApplicationUser
{
    public virtual ICollection<Repair> Repairs { get; set; }
}

当我运行Code First迁移时,这两个类都在同一个表中,这个表是具有正确的Discriminator和角色的AspNetUsers表。问题是,当我从系统中删除一些用户时,我也希望从我的数据库中删除所有车辆和修理但是因为在普通数据库中没有正确区分除了哪个用户的鉴别器之外我没有找到设置的方法cascade删除引用数据库(Vehicle和Repair)中正确表的外键约束,所以要么我得到一个异常,要么我的db中的外键设置为null。

这是实现级联删除的一种方式,还是应该更改我的模型,因为除此之外一切正常。

提前致谢!

1 个答案:

答案 0 :(得分:0)

试图解决类似问题并在这里结束,所以我将贡献我迄今为止学到的东西。在我的例子中,我有一个基础ApplicationUser,其中包含两个包含特定(实体)属性的继承类:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<HumanUser>().HasOptional(x => x.GlobalInventory).WithRequired(x => x.User).WillCascadeOnDelete(true);
        base.OnModelCreating(modelBuilder);
    }

我还将以下Fluid API代码添加到ApplicationDbContext:

        CreateTable(
            "dbo.GlobalInventories",
            c => new
                {
                    UserId = c.String(nullable: false, maxLength: 128),
                })
            .PrimaryKey(t => t.UserId)
            .ForeignKey("dbo.Users", t => t.UserId)
            .Index(t => t.UserId);

这是Code First为GlobalInventory推出的迁移部分。请注意,与HumanUser的外键连接没有“cascadeDelete:true”标志。这意味着当我删除父级时,将发生错误:

public class ApplicationUser : IdentityUser {

    [Required]
    public virtual GlobalInventory GlobalInventory { get; set; }
} 

public class HumanUser : ApplicationUser {

    [Required]
    public virtual GlobalInventory GlobalInventory { get; set; }
}


public class GlobalInventory {

    [Key, ForeignKey("User")]
    public string UserId { get; set; }

    [Required]
    public virtual ApplicationUser User { get; set; }
}

但是 - 如果我将GlobalInventory设为基本ApplicationUser类的属性,如下所示:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ApplicationUser>().HasOptional(x => x.GlobalInventory).WithRequired(x => x.User).WillCascadeOnDelete(true);
        base.OnModelCreating(modelBuilder);
    }

..并相应地修改模型构建:

        CreateTable(
            "dbo.GlobalInventories",
            c => new
                {
                    UserId = c.String(nullable: false, maxLength: 128),
                })
            .PrimaryKey(t => t.UserId)
            .ForeignKey("dbo.AspNetUsers", t => t.UserId, cascadeDelete: true)
            .Index(t => t.UserId);

然后GlobalInventory的迁移代码看起来是正确的,我可以删除用户知道还将删除GlobalInventory:

|  IMAGE |  Colour:         Red |
|        |  Weight:         1kg |
|        |  size:           1M  |
|        |  model:          xyz |

(当ApplicationUser定义为抽象类时,这也可以正常工作)

我不想将特定的实体属性附加到基类,所以这就是我目前所处的位置。当应用于我的继承类时,就好像Fluid API cascade-on-delete指定被忽略了,但是当应用于基类时却没有。