[英]Cascade delete on classes inherited from ApplicationUser(IdentityUser)
I have two classes that are inherited from ApplicationUser in ASP .NET Identity, classes are as follows : 我在ASP .NET Identity中有两个继承自ApplicationUser的类,类如下:
This is my ApplicationUser class 这是我的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;
}
}
And two classes that inherited it : 还有两个继承它的类:
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; }
}
When I run Code First migrations both classes are inside the same table which is AspNetUsers table with proper Discriminator and role. 当我运行Code First迁移时,两个类都在同一个表中,这个表是具有适当的Discriminator和角色的AspNetUsers表。 The problem is that when I remove some User from system I also want all vehicles and repair to be removed from my database but since in plain database there is no proper distinction beside discriminator of which user it is I didn't find a way to set cascade delete on foreign key constraints that reference proper tables in database (Vehicle and Repair) so instead either I got an exception or my foreign key in db is set to null.
问题是,当我从系统中删除一些用户时,我也希望从我的数据库中删除所有车辆和修理但是因为在普通数据库中没有正确区分除了哪个用户的鉴别器之外我没有找到设置的方法cascade删除引用数据库(Vehicle和Repair)中正确表的外键约束,所以要么我得到一个异常,要么我的db中的外键设置为null。
Is it a way to achieve cascade delete or should I change my model because from other than this everything is working fine. 它是实现级联删除的一种方式,还是我应该更改我的模型,因为除此之外一切正常。
Thanks in advance! 提前致谢!
Trying to solve a similar problem and wound up here, so I'll contribute what I've learned so far. 试图解决类似的问题,并在这里结束,所以我将贡献我迄今为止学到的东西。 In my case I have a base ApplicationUser with two inheriting classes containing specific (entity) properties:
在我的例子中,我有一个基础ApplicationUser,其中包含两个包含特定(实体)属性的继承类:
public class ApplicationUser : IdentityUser {
}
public class Server : ApplicationUser {
}
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 HumanUser User { get; set; }
}
I've also added the following Fluid API code to ApplicationDbContext: 我还在ApplicationDbContext中添加了以下Fluid API代码:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<HumanUser>().HasOptional(x => x.GlobalInventory).WithRequired(x => x.User).WillCascadeOnDelete(true);
base.OnModelCreating(modelBuilder);
}
Here's the migration part that Code First chucks out for GlobalInventory. 这是Code First为GlobalInventory推出的迁移部分。 Notice that the foreign key connection to HumanUser is without the "cascadeDelete: true" flag.
请注意,与HumanUser的外键连接没有“cascadeDelete:true”标志。 That means that when I delete the parent, errors will occur:
这意味着当我删除父项时,将发生错误:
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);
BUT - if I make GlobalInventory a property of the base ApplicationUser class instead , like so: 但是 - 如果我使GlobalInventory成为基本ApplicationUser类的属性,如下所示:
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; }
}
.. and modify the model building accordingly: ..并相应地修改模型构建:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ApplicationUser>().HasOptional(x => x.GlobalInventory).WithRequired(x => x.User).WillCascadeOnDelete(true);
base.OnModelCreating(modelBuilder);
}
Then the migration code for GlobalInventory looks right, and I can delete Users knowing that the GlobalInventory will be removed also: 然后GlobalInventory的迁移代码看起来是正确的,我可以删除用户知道GlobalInventory也将被删除:
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);
(This also works fine when ApplicationUser is defines as an abstract class) (当ApplicationUser被定义为抽象类时,这也可以正常工作)
I don't want to attach specific entity properties to the base class though, so this is where I'm currently stuck at. 我不想将特定的实体属性附加到基类,所以这就是我目前所处的位置。 It's as if the Fluid API cascade-on-delete designation gets ignored, when applied to my inheriting classes, but not when applied to the base class.
就像Fluid API cascade-on-delete指定在应用于我的继承类时被忽略一样,但是当应用于基类时却没有。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.