[英]Entity Framework 6.x cannot remove an attached entity in a relationship
我有一个非常简单的类似拍卖的应用程序。 使用EF 6.x并试图从父级(列表)中删除子级(出价)时,出现了很多奇怪的行为。 我正在删除应用程序中其他位置具有相似关系类型的实体,而没有任何问题。 涉及的实体:
public class Listing {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ListingID { get; set; }
[Required]
public bool Active { get; set; }
[Required]
[StringLength(128)]
public string UserID { get; set; }
[ForeignKey("UserID")]
public ApplicationUser User { get; set; }
public List<Bid> Bids { get; set; }
public Listing() {
User = new ApplicationUser();
Bids = new List<Bid>();
}
}
public class Bid {
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int BidID { get; set; }
[Required]
public decimal Amount { get; set; }
[Required]
public DateTime Created { get; set; }
[Required]
[StringLength(128)]
public string UserID { get; set; }
public int ListingID { get; set; }
[ForeignKey("UserID")]
public ApplicationUser User { get; set; }
[ForeignKey("ListingID")]
public Listing Listing { get; set; }
public Bid() {
User = new ApplicationUser();
Listing = new Listing();
}
}
public class ApplicationUser : IdentityUser {
public List<Listing> Listings { get; set; }
public List<Bid> Bids { get; set; }
public ApplicationUser() {
Listings = new List<Listing>();
Bids = new List<Bid>();
}
}
在这种特定情况下,我要按用户查询出价并将其删除:
public bool RemoveBids(string offenderUserID) {
using (var db = new MyDbContext()) {
var bids = db.Bids
.Include(l => l.Listing)
.Where(x => x.UserID == offenderUserID && x.Listing.Active == true);
foreach (var bid in bids) {
bid.User = null;
bid.Listing = null;
db.Bids.Remove(bid);
db.Entry(bid).State = EntityState.Deleted;
}
return db.SaveChanges() == 1 ? true : false; //exception on SaveChanges()
}
}
在我使bid.Listing无效之前,我得到了DbEntityValidationException,它表示必须使用Listing的字段。 在调试器中浏览它表明EF尝试将新实体添加到bid.User和bid.Listing。 疯狂...但是好。 我一直继续下去,最终得到上面看到的东西……这导致另一个xxx:
UserName字段为必填。
用户名作为Identity Framework的一部分位于IdentityUser(AspNetUsers表)中。
它仍在尝试添加ApplicationUser ...以某种方式在某处? 我在上面查询的图中的任何地方都没有ApplicationUser对象。 我只是看不到。
检查表将显示字段与上面的实体完全相同。
这是我的第一个重要的Code-First项目。 我从事过一些带有edmx模型的相当大的DB-First项目,并且从未记得遇到过如此多的障碍和奇怪的“陷阱”。 大多数事情似乎都可以正常工作。 我应该转换一下东西吗? 我已经在这么简单的事情上浪费了太多时间。 我想喜欢EF。 经过数天的故障排除后,我喜欢它的主意……但感觉并不是特别有效。
提前致谢。
public Bid() {
User = new ApplicationUser();
Listing = new Listing();
}
public Listing() {
User = new ApplicationUser();
Bids = new List<Bid>();
}
编辑 。 上面的代码是错误的。 删除那些初始化器。 它们仅应存在于集合中。 之所以会出现这些奇怪的错误,是因为每次加载Bid
或Listing
对象时,都是在创建缺少必需参数的全新对象,因此,在调用savechanges时,您最终会以EF抱怨某些必需参数缺失。
我最初将其视为Bid
类的属性。
public int ListingID
但是你有...
bid.Listing = null;
从逻辑上讲,这没有任何意义。 在第一行代码中,您说的是每个出价都需要使用Listing
属性。 但是,如果将其设置为null,则表示“此出价不需要此列表”。
我认为您可以安全地删除将导航属性设置为null的代码行,因为它们什么也没做,因为无论如何您只是删除Bid
对象。
我有一个类似的问题,对我来说,我好像在各自班级中没有正确建立“父母与孩子”之间的关系。
我的解决方法是将以下指定的属性添加到Child类中,以表示其父ID的属性
public class Child
{
[Key, Column(Order = 1)]
public string Id { get; set; }
[Key, ForeignKey("Parent"), Column(Order = 2)] // adding this line fixed things for me
public string ParentId {get; set;}
}
public class Parent
{
[Key, Column(Order = 1)]
public string Id { get; set; }
...
public virtual ICollection<Child> Children{ get; set; }
}
查看您的代码,就像在Bid类中一样,其父类是ListingId?
如果是这样,那将是修改的行,如下所示:
[Key, ForeignKey("Listing"), Column(Order = 2)]
public int ListingID { get; set; }
完成此操作后,我还可以删除以下行,因此仅需要.Remove调用:
db.Entry(bid).State = EntityState.Deleted;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.