几天已经沉醉在一个问题中了,现有一Material实体和Supplier实体,这两个表有个中间表(实体)MaterialWithSupplier。其中MaterialWithSupplier的结构为
[Key] [StringLength(150)] public string Id { get; set; } [ForeignKey("Material")] public string MaterialNo { get; set; } public virtual Material Material { get; set; } [ForeignKey("Supplier")] public int SupplierId { get; set; } public virtual Supplier Supplier { get; set; }
在本人想删除某个Material的时候,原因是外键关联本人要先删除MaterialWithSupplier,所以
var MaterialWithSupplier = db.MaterialWithSuppliers.Where(m => m.MaterialNo == MaterialNo).ToList(); if (MaterialWithSupplier.Count > 0) db.MaterialWithSuppliers.Remove(MaterialWithSupplier[0]);
这样做了,但是这一操作把MaterialWithSupplier表中全部记录给删除了,本人觉得很是奇怪,希望各位大大帮帮本人,到底是啥原因啊?愁死本人了!
解决方案
10
调试呗。看看取到的数据是多少。看看删除的时候。那个tolist之后的数据集个数是多少。
不过,本人看你ID用的是String类型?改成Int32吧。int型的。
代码本人看没问题呢。调试一下就知道哪里出问题了。
不过,本人看你ID用的是String类型?改成Int32吧。int型的。
代码本人看没问题呢。调试一下就知道哪里出问题了。
20
没什么特殊的,多对多其实拆开来就是两个方向的一对多
EF原则上是不直接处理关系表的
dbfirst,可以去外键那里启用级联删除,然后只需要删除主键纪录Material或Supplier就行
codeFirst中则更直接,压根都不需要MaterialWithSuppliers这个关系实体类了,而且级联删除也不需要再去关心外键能否开启级联删除了,由EF来完成
用FluentAPI配置映射关系就是
this.HasRequired(m => m.Material)
.WithMany(m => m.MaterialWithSuppliers)
.HasForeignKey(m => m.MaterialNo)
.WillCascadeOnDelete(true);
Supplier同上
隐式
Material类
this.HasRequired(m => m.Supplier)
.WithMany(m => m.Materials)
.HasForeignKey(m => m.SupplierId)
.WillCascadeOnDelete(true);
Supplier类
this.HasRequired(m => m.Material)
.WithMany(m => m.Supplier)
.HasForeignKey(m => m.MaterialNo)
.WillCascadeOnDelete(true);
当然也可以用HasMany().WithRequired().Map()
不管怎么,此时你都不再需要MaterialWithSuppliers这个类了
你的代码中没看到哪里有循环,看样子你是想删除Material和关联的MaterialWithSuppliers,假如级联删除没启用
你可以先将要删的东西全查出来
var material = db.Material.Include(m => m.MaterialWithSuppliers).Single(m => m.MaterialNo == MaterialNo);
db.MaterialWithSuppliers.RemoveRange(material.MaterialWithSuppliers);这句不需要了
db.Material.Remove(material);
db.SaveChanges();
EF原则上是不直接处理关系表的
dbfirst,可以去外键那里启用级联删除,然后只需要删除主键纪录Material或Supplier就行
codeFirst中则更直接,压根都不需要MaterialWithSuppliers这个关系实体类了,而且级联删除也不需要再去关心外键能否开启级联删除了,由EF来完成
用FluentAPI配置映射关系就是
this.HasRequired(m => m.Material)
.WithMany(m => m.MaterialWithSuppliers)
.HasForeignKey(m => m.MaterialNo)
.WillCascadeOnDelete(true);
Supplier同上
隐式
Material类
this.HasRequired(m => m.Supplier)
.WithMany(m => m.Materials)
.HasForeignKey(m => m.SupplierId)
.WillCascadeOnDelete(true);
Supplier类
this.HasRequired(m => m.Material)
.WithMany(m => m.Supplier)
.HasForeignKey(m => m.MaterialNo)
.WillCascadeOnDelete(true);
当然也可以用HasMany().WithRequired().Map()
不管怎么,此时你都不再需要MaterialWithSuppliers这个类了
你的代码中没看到哪里有循环,看样子你是想删除Material和关联的MaterialWithSuppliers,假如级联删除没启用
你可以先将要删的东西全查出来
var material = db.Material.Include(m => m.MaterialWithSuppliers).Single(m => m.MaterialNo == MaterialNo);
db.MaterialWithSuppliers.RemoveRange(material.MaterialWithSuppliers);这句不需要了
db.Material.Remove(material);
db.SaveChanges();
10
EF默认是级联删除的,除非你手动关闭外键删除,并设置WillCascadeOnDelete(false)(或在查出来Material后设置.MaterialWithSuppliers= null应该也可以)
当你需要级联删除时,还是像7#那样Include即可。
当你需要级联删除时,还是像7#那样Include即可。