【问题标题】:how to load a table query by reference table in EF6如何在 EF6 中通过引用表加载表查询
【发布时间】:2025-12-15 03:30:02
【问题描述】:

我使用实体框架6,有两个实体:Category & Item,它们有一对多的关系,Item 实体有一个属性owner

就是这样,我的要求是构建一个查询,结果包含所有类别,每个类别都包含一些所有者等于某个值的项目。

类别类:

public class Category {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; private set; }
    public string Name { get; set; }
    public int? PId { get; private set; }
    [ForeignKey("PId")]
    public Category Parent { get; set; }
    public ICollection<Category> Subcategories { get; set; }
    //[ForeignKey("CategoryId")]
    public ICollection<Item> Items { get; set; }

    public Category() {
        Subcategories = new List<Category>();
        Items = new List<DataItem>();
    }
}

物品类别:

public class Item {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; private set; }
    public string Name { get; set; }
    public int Owner { get; set; }
    public int CategoryId { get; set; }
    [ForeignKey("CategoryId")]
    public Category Category { get; set; }
}

例如,有一些测试数据如下:

结果需要包含 11 拥有的某些项目的所有这些类别。 如何进行此查询?

【问题讨论】:

  • 在这种情况下,您可能需要使用左连接,例如:Category.Id == Item.CategoryId &amp;&amp; owner == 11
  • 你是对的,但我不知道如何为此编写 EF 代码。
  • 浏览this msdn 文档,您将对如何使用 linq 左连接有基本的想法。

标签: c# sql entity-framework-6


【解决方案1】:

Category.Items.Filter( item =&gt; item.owner == '11') 应该为您解决问题,以防我正确理解问题。

【讨论】:

  • 是的,你的回答是可以的,但是这段代码是在查询后过滤的,会浪费查询,如果Item的数量很大,会导致性能不佳。
  • 我认为查询应该被延迟评估,因此过滤器应该是查询子句的一部分,而不是过滤内存中的结果。这不正确吗?
【解决方案2】:

var cats = from category in _context.Categories
                           from item in _context.DataItems.Where(i => i.CategoryId == category.Id && i.Owner == id).DefaultIfEmpty()
                           select new { Category = category, Items = item };

【讨论】:

  • 此代码进行左内连接并将自动创建类别树。