【问题标题】:Linq Foreign Key SelectLinq 外键选择
【发布时间】:2015-03-17 03:03:46
【问题描述】:

我有两个表,具有一对多(文章)对多(详细信息)的关系。详细信息可能不包含特定文章条目的任何数据。

文章:ID、标题、Numb (PK)、名称

详细信息:Id (PK)、Person、Numb (FK)、姓名

在实体框架中,有相应的导航属性,它显示了正确的 One:Many 关系。

我想要做的是获取与最终用户的查询匹配的所有文章(按“名称”)以及来自详细信息表(Id、Person、Numb、Name)的所有数据(如果有)。

我坚持的是,现在我可以很好地查询文章 (var article = db.Articles.Where(b => b.Name.Equals(name));),但是虽然结果确实在文章的每一行上都包含了 Details.Numb 的 HashSet,但该 HashSet 中没有数据。 Article.Numb => Details.Numb 的数据库中有相应的相应条目。

【问题讨论】:

    标签: c# linq entity-framework-6


    【解决方案1】:

    其实有两种方法可以实现。

    1. 启用延迟加载。
    2. 如其他答案所述,调用 Include 方法。

    使用延迟加载有关详细信息,请参阅 msdn article

        db.ContextOptions.LazyLoadingEnabled = true;
    

    使用 Include 方法

        var article = db.db.Articles.Include("Details").Where(b => b.Name.Equals(name))).FirstOrDefault();
    

    【讨论】:

    • 是否可以在没有 FirstOrDefault 的情况下使用 Include?预计会返回多个条目。
    • 看起来关系可能有问题(?)。当我中断调试器并检查 db.Articles 结果视图时,在 Details 中具有有效 FK 的任何结果都没有 Details 的结果。
    • 使用 LINQPad,我能够成功地查询(使用 from a in Articles where a.Name.Equals("value") select a)数据库并返回结果。在这种情况下,它从 Articles 返回 3 个结果,然后其中一个结果的 EntitySet
      有两个结果。理想情况下,这是我希望显示数据的方式。在我的 Web API 应用程序中使用完全相同的查询,我仍然在通过 LINQPad 返回 EntitySet 的相同结果中看到 Article.Detail.Count == 0。
    • 好的,在将此作为解决方案发布之前,我想看看是否有更清洁的方法来执行此操作,因为这会产生所需的结果。 '从 db.Articles.Where(a => a.Name.Equals("value")).Select(a => new {a.Title,a.Numb,a.Name}) 中选择 a;。输出提供每个行项目,以及项目的详细信息数组(包含详细信息表中的所有字段)(而不是创建文章到详细信息的一对一输出)。
    • @TrevorSeward 没有包括在您的场景中不起作用。如果未启用延迟加载,您的上述查询将不起作用,否则它会起作用。虽然延迟加载可以完成工作,但我总是更喜欢使用 Include。
    【解决方案2】:

    在执行查询(并关闭连接)后,您需要告诉 EF 在结果集中包含详细信息:

    var article = db.Articles
        .Include("Details")
        .Where(b => b.Name.Equals(name))
        .FirstOrDefault();
    

    【讨论】:

    • 我有类似的问题。使用 include() 将不起作用,因为外键是使用 EF Code First 生成的。如果我在include 中包含外键,它将找不到任何内容,因为我的模型没有名为[foreign key column name] 的列。这是我最初的问题:https://social.msdn.microsoft.com/Forums/vstudio/en-US/d49772c9-c108-4418-b782-e231f60b6ffc/foreign-id-attribute-cannot-be-accessed-in-linq-query-for-an-object-of-a-class-that-has-a-list-of?forum=csharpgeneral你能帮忙吗?
    【解决方案3】:

    在导航属性上使用.Include(),它会将整个内部对象带入查询结果中。仅当您从内部对象中过滤或选择项目时,它才会自动执行,否则您必须手动请求包含。

    【讨论】:

      【解决方案4】:

      例子:

      var allProducts = _db.Products.Include(d => d.Producer).ToList();
      

      如果您不确定,请始终使用Include,而不是延迟加载。

      【讨论】:

      • 如何让 Producer 出现在 datagridview 中? dgv 无法读取它
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 2014-02-16
      • 2015-09-24
      • 1970-01-01
      • 2012-10-19
      • 1970-01-01
      相关资源
      最近更新 更多