为什么导航属性集合总是空的

本文关键字:集合 导航 属性 为什么 | 更新日期: 2023-09-27 18:16:02

为什么在下面的程序中导航属性Assemblies和Components总是空的?

// 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();
}

CreateBOM方法绝对工作良好,并创建正确的记录,但ReadBOM总是给出count = 0!(

为什么导航属性集合总是空的

我认为你的代码工作得很好,问题是你从你的DB和Item (Bike)得到的,当你创建BOOM实体实例时,这与Component无关。

如果你尝试:

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

您将得到预期的结果,因为bike只是与Assembly相关

试试这个

line1.AssemblyID = bike.ItemID;
line1.ComponentID = frame.ItemID;  

如果您的ItemID是由DB自动生成的,那么您可以在创建BOM之前创建SaveChanges()