31

I read quite a number of posts of programmers that run into the Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values -exception when using a self-referencing relationship in Entity Framework.

I am trying to get a parent-child relationship to work:

public class Category {
    public int CategoryId { get; set; }
    public string Name { get; set; }
    public int ParentId { get; set; }
    public Category Parent { get; set; }
    public List<Category> Children { get; set; }
}

This is the configuration I use (Fluent API):

Property(c => c.ParentId).IsOptional();
HasMany(c => c.Children).WithOptional(c => c.Parent).HasForeignKey(c => c.ParentId);
//HasOptional(c => c.Parent).WithMany(c => c.Children).HasForeignKey(c => c.ParentId);

Both the HasMany() and HasOptional() configurations result in a "Unable to determine a valid ordering for dependent operations..." exception when I try to save a new category like this:

context.Categories.Add(new Category { Name = "test" });

I don't understand why EF doesn't insert the Category with a null parentId. The database allows the ParentId foreign key to be null.

Would you be able to tell me how to do this?

Slauma
  • 175,098
  • 59
  • 401
  • 420
Julius
  • 2,784
  • 6
  • 32
  • 54

2 Answers2

35

You must define the ParentId in the category class as nullable to use it as the foreign key property for an optional relationship:

public int? ParentId { get; set; }

An int property cannot take the value null and therefore cannot represent a NULL as value in a database column.

Slauma
  • 175,098
  • 59
  • 401
  • 420
1

Since someone asked in a comment about doing this with attributes. You can also utilize data annotations to set this up. Using the same example as above:

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

public class Category {
    // You can also add [DatabaseGenerated(DatabaseGeneratedOption.Identity)]  
    // as an attribute, if this field is to be generated by the database
    [Key] // Define this as the primary key for the table
    public int CategoryId { get; set; }
    public string Name { get; set; }

    [ForeignKey(nameof(Parent))]  // Link the Parent object to the ParentId Foreign Key
    public int? ParentId { get; set; }
    public Category Parent { get; set; }

    public List<Category> Children { get; set; }
}

This is tested and works in EF 6.

airsouth
  • 43
  • 4