繁体   English   中英

Entity Framework 6.x无法删除关系中的附加实体

[英]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>();
}

编辑 上面的代码是错误的。 删除那些初始化器。 它们仅应存在于集合中。 之所以会出现这些奇怪的错误,是因为每次加载BidListing对象时,都是在创建缺少必需参数的全新对象,因此,在调用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM