Reinstantiating EF classes with one-to-many relationship and compound key of strings

拈花ヽ惹草 提交于 2019-12-20 07:15:00

问题


I have the following EF Code First classes, which appear to be working to a point. I also have Initialization code that seeds these tables with data from elsewhere that is lengthy, and seems (I hope) inconsequential to my question. Or at the least when I seed manually I see the same behavior problem.

Note, that these tables use strings as their primary keys, and not ID's. Also note that the SubCategory table has a compound primary key that includes the parent table, Category's primary key, CategoryCode. This is, perhaps, old school, ISAMish, but it is what I have to work with, and is otherwise logical.

public class Category
{
  [Key]
  public string CategoryCode { get; set; }
  public string Description { get; set; }

  public List<SubCategory> Sub Categories { get; set; }

  public Category()
  {
    this.SubCategories = new List<SubCategory>();
  }
}

public class SubCategory
{
  [Key, Column(Order = 0)]
  public string CategoryCode { get; set; }
  [Key, Column(Order = 1)]
  public string SubCategoryCode { get; set; }
  public string Description { get; set; }
  public Category Category { get; set; }

  public SubCategory() { }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  // Configures the one-many relationship between Categories and 
  //   SubCategories, and established the Foreign Key in SubCategories
  modelBuilder.Entity<Category>()
    .HasMany<SubCategory>(c => c.SubCategories)
    .WithRequired(s => s.Category)
    .HasForeignKey<string>(s => s.CategoryCode);
}

This structure allows the same SubCategoryCode, say "CONTR" to be used more than once for different CategoryCodes, such as "REHAB" and "MAINT". A sample of data looks like this:

Categories

CategoryCode    Description
==================  =========================
BANK    Costs of banking fees and expenses
FUND    Funding Loans/Pmnts
INSUR   Property Insurance
MAINT   Maintenance Expenses
REHAB   Rehabilitation & Renovation Expenses

SubCategories

CategoryCode    SubCategoryCode Description
==================  =====================   ===========
FUND    LOAN    Monies borrowed to Entity
FUND    PMNT    Monies paid back by Entity
INSUR   BUILD   Builders Risk policy, including liability
INSUR   LANDL   Landlord policy, including liability
INSUR   MISC    Miscellaneous/Other
MAINT   CONTR   Contractor invoices, (labor, Materials, fees)
MAINT   MATL    Materials & Tooling
REHAB   CONTR   Contractor invoices, (labor, Materials, fees)
REHAB   MATL    Materials & Tooling

Note that I seemed to need to specify a default constructor to add instantiation of the List member, or this property ends up being null in instantiated Category classes.

Also note that I wish to have both classes include references to each other - i.e., Category has a List member to hold its constituent SubCategory data, and SubCategory has a Category member to hold a reference to its parent.

It is here that I have the greatest issue. If I just execute the following, I get List of populated Category classes; however, each of those objects' List of SubCategory objects is empty (not null, but there with 0 items). Now, before we blame the default constructor establishing the empty List here, note that without that code each of the Category instances contain a Null reference to their SubCategory List.

using (var db = new BusinessDBContext())
{
  var Categories = db.Categories.Where(c => c.CategoryCode == "FUND").ToList();
}

But, if I add instantiating a List of SubCategory, the Category's in the List of Category will now have populated lists of SubCategory's within. They aren't there until I instantiate the SubCategories. And, it doesn't seem to matter if that happens before or after the query for Categories.

using (var db = new BusinessDBContext())
{
  var Categories = db.Categories.Where(c => c.CategoryCode == "FUND").ToList();
  var SubCategories = db.SubCategories.Where(s => s.CategoryCode == "FUND").ToList();
}

What am I missing, or otherwise misunderstanding?


回答1:


Why SubCategories is null or with 0 item because you don't include this relation that it is Eager loading. if you want to use lazy loading you can use virtual keyword in your navigation property:

Lazy Loading:

public virtual List<SubCategory> SubCategories { get; set; }

Eager Loading:

db.Categories.Where(c => c.CategoryCode == "FUND").Include(x => x.SubCategories ).ToList();

Read More.



来源:https://stackoverflow.com/questions/49516733/reinstantiating-ef-classes-with-one-to-many-relationship-and-compound-key-of-str

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!