![](/img/trans.png)
[英]Deleting Entity in Many to Many Relationship Leaves Orphans in Relationship Table
[英]Entity Framework Many to Many relationship leaves data in joining table
我尝试使用“实体框架代码优先”进行多对多关系。
对象是CARD
和USER_LIST
; 一个CARD
可以分配有许多USER_LIST
,而一个USER_LIST
可以分配给许多CARD
。
这些类的定义如下:
public partial class CARD : DBEntityItem {
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CARD_ID { get; set; }
[StringLength(500)]
public string SHORT_DESC { get; set; }
public int STAGE_ID { get; set; }
public int GROUP_ID { get; set; }
public int FLAGS { get; set; }
[StringLength(30)]
public string OFFICE_APP_REF { get; set; }
[StringLength(7)]
public string CARD_COLOUR { get; set; }
public int CTYPE_ID { get; set; }
public virtual GROUP GROUP { get; set; }
public virtual CARD_TYPE CARD_TYPE { get; set; }
public virtual STAGE STAGE { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<USER_LIST> USER_LIST { get; set; }
[NotMapped]
public CardFlags FlagOptions { get; set; }
public enum CardFlags {
None = 0,
Blocked = 1,
Unexpected = 2,
Emergency = 4,
Failed = 8
}
public CARD()
: base("CARD", "CARD_ID") {
USER_LIST = new HashSet<USER_LIST>();
}
}
public partial class USER_LIST : DBEntityItem {
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int USER_ID { get; set; }
[Required]
[StringLength(100)]
public string USER_NAME { get; set; }
[Required]
[StringLength(250)]
public string PASSWORD { get; set; }
[StringLength(250)]
public string EMAIL { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<PREFERENCE_VALUE> PREFERENCE_VALUE { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<USER_PERMISSIONS> USER_PERMISSIONS { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<USER_TASK> USER_TASK { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<CARD> CARD { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<CHANGE_NOTE> CHANGE_NOTE { get; set; }
public USER_LIST()
: base("USER_LIST", "USER_ID") {
PREFERENCE_VALUE = new HashSet<PREFERENCE_VALUE>();
USER_PERMISSIONS = new HashSet<USER_PERMISSIONS>();
USER_TASK = new HashSet<USER_TASK>();
CARD = new HashSet<CARD>();
}
}
忽略来自DBEntityItem
的继承以及生成的构造函数链,因为这只是一个用于为Entities提供某些附加功能的类。
在OnModelCreating
定义了多对多映射,如下所示:
modelBuilder.Entity<CARD>()
.HasMany(e => e.USER_LIST)
.WithMany(e => e.CARD)
.Map(m => {
m.MapLeftKey("CARD_ID");
m.MapRightKey("USER_ID");
m.ToTable("CARDUSER");
});
这是由于“ CARDUSER”是数据库中的现有表。
将建立一个List<USER_LIST>
,并将其设置为CARD
对象的USER_LIST
属性。 调用SaveChanges()
,这将导致以下结果(按预期):
MyCardObject.USER_LIST = MyListOfUsers;
MyDBContext.SaveChanges();
可以看出,正确的条目已根据需要插入到CARDUSER表中。
当我尝试删除卡时出现了我遇到的问题:
MyDBContext.CARD.Remove(MyCardObject);
MyDBContext.SaveChanges();
以上将从CARD表中删除CARD记录; 但是,CARDUSER中与该CARD有关的所有记录仍然存在:
我遇到以下问题,并希望这能回答我的问题:
但是,我已经在DBContext中定义了“多对多”映射,而无需显式定义CARDUSER
对象,因此我无法将每个CARDUSER
对象的State
设置为Deleted
。
为什么此数据在CARDUSER表中徘徊,并且如何进行设置,以使CARDUSER中的CARD_ID和USER_ID字段都是正确的强制外键值? 我尝试在数据库本身内的CARDUSER表上设置外键约束; 但是,如果执行此操作,则当我对CARD
对象设置USER_LIST
属性,然后尝试保存USER_LIST
的更改时,会导致CARDUSER
违反外键,并且系统尝试重新插入所有已经对CARD
设置了。
在多对多关系中,您必须具有联结/桥表。
您可以在您发布的链接中看到他有一个联结表。
将外键约束添加到联接表中时,您处在正确的轨道上。 SQL Server(默认情况下)不会通过外键关系cascade
删除操作,这就是您(正确地)收到错误的原因。 如果将外键定义为on delete cascade
,则将获得所需的行为。
或者,您可以定义没有级联行为的外键。 如果这样做,则必须确保手动删除联接表中的条目。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.