本文介绍了通过一对多关系和字符串的复合键重新实例化EF类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下EF代码优先类,它们似乎在起作用.我还具有初始化代码,这些代码使用来自其他地方的冗长数据填充了这些表,并且(希望)与我的问题无关紧要.或者至少当我手动播种时,我会看到相同的行为问题.

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.

请注意,这些表使用字符串作为其主键,而不是ID.还要注意,SubCategory表具有一个复合主键,该主键包括父表,Category的主键CategoryCode.这也许是老派的ISAMish,但这是我必须处理的,否则是合乎逻辑的.

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

此结构允许将相同的SubCategoryCode(例如"CONTR")多次用于不同的CategoryCode,例如"REHAB"和"MAINT".数据示例如下:

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

请注意,我似乎需要指定默认构造函数以添加List成员的实例化,否则此属性最终在实例化的Category类中为null.

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.

还要注意,我希望两个类都包含相互引用的内容,即Category具有一个List成员来保存其组成SubCategory数据,SubCategory具有Category成员来对其父级进行引用.

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.

在这里,我有最大的问题.如果仅执行以下命令,则将显示已填充的Category类的列表;但是,这些对象的SubCategory对象列表中的每个都是空的(不为null,但有0个项目).现在,在我们责怪默认构造函数在此处建立空列表之前,请注意,没有该代码,每个Category实例都包含对其子类别列表的Null引用.

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

但是,如果我添加实例化SubCategory的列表,则类别列表中的类别现在将在其中填充SubCategory的列表.在我实例化SubCategories之前,它们不存在.并且,这似乎无关紧要,是否发生在查询类别之前或之后.

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?

推荐答案

为什么SubCategories为null或带有0项,因为您不包括此关系,因此它是急切加载的.如果要使用延迟加载,可以在导航属性中使用virtual关键字:

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:

延迟加载:

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

急切加载:

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

了解详情.

这篇关于通过一对多关系和字符串的复合键重新实例化EF类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-19 18:08