I have an Order table that contains a nullable foreign key to another table called Product (each order can only map to one product). Each order will only point to one product. The relation is configured by Fluent API as shown here (in Entity Framework 6.1.3):
public class OrderConfiguration : EntityTypeConfiguration<Order> { public OrderConfiguration() { // the same issue still happens if switched to 'HasRequired' HasOptional(o => o.Product) .WithMany() .HasForeignKey(o => o.ProductKey) .WillCascadeOnDelete(false); } } Now, when I call Remove (or RemoveRange) on Order, why does it set the foreign key ProductKey in Order to null? What is causing this behavior to happen and how do I prevent this?
As a side note, please correct me if I am wrong, but in my understanding "Cascade On Delete" shouldn't have anything to do with the issue here (setting WillCascadeOnDelete(false) doesn't do anything here, nor does Conventions.Remove<OneToManyCascadeDeleteConvention>() do anything here). It is meant to cascade to dependent entities when deleting the principal entity, not the other way around.
Why this behavior exists? Do I really have to copy the entity or store the foreign keys' value before delete?
public Order RemoveOrder(int orderID) { using (var context = new MyDBContext()) { var order = context.Order .Where(o => o.OrderID == orderID) .FirstOrDefault(); if (order == null) return null; // Here foreign key `productKey` on `order` is not null yet var removed = context.Orders.Remove(order); // Now `productKey` on both 'order' and 'removed' are null context.SaveChanges(); return removed; } } These are the entity clases if needed! (There is no other configuration for this navigation property except the one showed above. There is also no ON DELETE CASCADE or any constrain set in the DB as far as I can see.)
public class Order { [Key] public int OrderID { get; set; } public int? ProductKey { get; set; } public string PONumber { get; set; } public virtual Product Product {get; set; } } public class Product { [Key] public int ProductKey { get; set; } public string ProductName { get; set; } } For context I was refactoring a class that were originally using TableAdapters. In some cases it follows this pattern (retreive the data, remove, and return the retreived data by using OUTPUT DELETED.*). These bug aren't caught by tests and causes some methods to always return false when comparing to that field, and GridView link links to nowhere.
context.Orders.Remove(order);and saving changes, the order is not removed, only itsProductKeyis set to null? Could you share theOderandProductclasses to make this reproducible?SaveChanges. TheRemove()method returns the removed entity, which is further needed. And yes, let me provide the entity class removing all unrelated fields!EntityStateof the entity? If so, I'm not sure how that will help. Or do you mean to clone the whole entity?