Caltor Caltor - 1 month ago 9
C# Question

Why is navigation property collection always empty

Why are the navigation properties Assemblies and Components always empty in the following programs?

// Item.cs
public class Item
{
public int ItemID { get; set; }
public string Desc { get; set; }

public virtual ICollection<BOM> Assemblies { get; set; }
public virtual ICollection<BOM> Components { get; set; }
}

// BOM.cs
public class BOM
{
[Key, Column(Order = 0)]
public int AssemblyID { get; set; }

[Key, Column(Order = 1)]
public int ComponentID { get; set; }

public int Qty { get; set; }

public virtual Item Assembly { get; set; }
public virtual Item Component { get; set; }
}

// TestDbContext.cs
public class TestDbContext : DbContext
{
public TestDbContext()
: base("name=Model1")
{
Database.SetInitializer<TestDbContext>(new DropCreateDatabaseIfModelChanges<TestDbContext>());
}

public virtual DbSet<Item> Items { get; set; }
public virtual DbSet<BOM> BOMs { get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<BOM>()
.HasRequired<Item>(b => b.Assembly) // BOM requires Assembly Item
.WithMany(b => b.Assemblies) // Item includes many Assemblies (BOMs)
.HasForeignKey(b => b.AssemblyID)
.WillCascadeOnDelete(false);

modelBuilder.Entity<BOM>()
.HasRequired<Item>(b => b.Component) // BOM requires Component Item
.WithMany(b => b.Components) // Item include many Components (BOMs)
.HasForeignKey(b => b.ComponentID)
.WillCascadeOnDelete(false);


base.OnModelCreating(modelBuilder);
}
}

// TestController.cs
public string CreateBOM()
{
// Create the items
Item bike = new Item();
bike.Desc = "Bike";
db.Items.Add(bike);

Item frame = new Item();
frame.Desc = "Frame";
db.Items.Add(frame);

Item wheel = new Item();
wheel.Desc = "Wheel";
db.Items.Add(wheel);

// Create the Bill Of Materials
BOM line1 = new BOM();
line1.Assembly = bike;
line1.Component = frame;
line1.Qty = 1;
db.BOMs.Add(line1);

BOM line2 = new BOM();
line2.Assembly = bike;
line2.Component = wheel;
line2.Qty = 2;
db.BOMs.Add(line2);

db.SaveChanges();

return "BOM has been created!";
}

public string ReadBOM()
{
Item bike = db.Items.Find(3);
// The following line always returns 0
return "Components: " + bike.Components.Count.ToString();
}


The CreateBOM method works absolutely fine and creates the correct records but the ReadBOM always gives a count = 0! :(

Answer

I think your code is working well, the issue is you are getting from your DB an Item (Bike) that was not related as a Component when you create BOOM entity instance.

If you try:

return "Assemblies: " + bike.Assemblies.Count.ToString();

You will get the expected result, because bike was just related as Assembly

Comments