C# LINQ到实体的奇怪行为包括

C# LINQ到实体的奇怪行为包括,c#,.net,mysql,join,linq-to-entities,C#,.net,Mysql,Join,Linq To Entities,我意识到我不完全理解LINQ to Entities中的Include方法 例如,以下面的两个代码段为例。我希望它们产生相同的输出(尽管第一个版本可能更有效,因为它避免了JOINs) 第一个代码段正确地输出了{Edition Id}-{Edition Title},而第二个代码段意外地输出了{Book Id}-{Edition Title},并且只给出了每本书的第一版 发生什么事了?是否有一种方法可以使用包含来实现所需的输出 编辑1:MySql数据看起来像(已更正的): 请注意,没有Id=8或I

我意识到我不完全理解LINQ to Entities中的
Include
方法

例如,以下面的两个代码段为例。我希望它们产生相同的输出(尽管第一个版本可能更有效,因为它避免了
JOIN
s)

第一个代码段正确地输出了
{Edition Id}-{Edition Title}
,而第二个代码段意外地输出了
{Book Id}-{Edition Title}
,并且只给出了每本书的第一版

发生什么事了?是否有一种方法可以使用
包含
来实现所需的输出

编辑1:MySql数据看起来像(已更正的):

请注意,没有Id=8或Id=9的
Edition

上面的代码是我的完整代码,在
Page\u Load
中,对于一个空的测试页面

编辑2:我已经测试了以下内容,它们没有什么区别:

  • var author=db.Authors.Include(“Books.Editions”).AsEnumerable().First()
  • var author=db.Authors.Include(“Books.Editions”).Single(o=>o.Id==1)
  • var author=db.Authors.Include(“Books”).Include(“Books.Editions”).First()
  • 编辑3:如果启用延迟加载,则以下操作有效(在代码段2中):

    (我想这与代码片段1基本相同。)

    但是,无论延迟加载如何,这仍然会返回奇怪的输出:

    var author = db.Authors.Include("Books.Editions").First();
    
    编辑4:我真的很抱歉,我曲解了上面的表格结构。(我正在经历这样的一天。)现在它被更正了,以显示多对多的关系。请参见编辑1

    还有

    ((ObjectQuery)db.Authors.Include("Books.Editions").AsEnumerable())
      .ToTraceString()
    


    CASE
    语句很有趣,因为我的MySql字段都不可为空。

    实体框架提供程序编译LINQ语句中的
    First()
    表达式时可能存在错误。当涉及到
    Include
    时,有时会出现一些奇怪的情况:

    尝试将第二个代码段改写为:

    using (var db = new Db()) {
        var author = db.Authors.Include("Books.Editions").AsEnumerable().First();
        foreach (var book in author.Books)
        {
            foreach (var edition in book.Editions)
            {
                Response.Write(edition.Id + " - " + edition.Title + "<br />");
            }
        }
    }
    

    编辑2:鉴于生成了疯狂的sql输出,问题很可能出在您的MySQL EF提供程序中。

    能否显示作者、书籍和版本表的全部内容?我猜你那里的数据比看上去的要多,甚至可能是重复的信息,include语句正在对其重新排序,使
    First()
    返回不同的作者。我必须同意这里的@d\u r\w。你能试着输出作者和书吗?@d_r_w@John看我的编辑。另外,如果我输出
    edition.Id+“-”+book.Id+“-”+author.Id
    它将获得正确的图书Id和作者Id,但版本Id的输出与图书Id相同。您是否尝试添加.Include(“图书”)以及当前的Include?这就是我需要的。实体框架的MySQL提供程序似乎到处都是bug,尤其是在连接方面。我不太熟悉MySQL和EF,或者它的任何缺点,但是如果你想保证你的属性被正确导航并且你正在使用MySQL,你必须按照第一个片段的方式来做。谢谢你的建议,但是我担心输出是一样的。如果我将
    First()
    替换为
    Single(o=>o.Id==1)
    @James,也是一样的。你能看看我的编辑,告诉我们那条语句的输出是什么吗?看我的编辑。我还错误地指定了我的表结构,我忘记了存在多对多关系。现在更正了。对不起/
    var author = db.Authors.First();
    
    var author = db.Authors.Include("Books.Editions").First();
    
    ((ObjectQuery)db.Authors.Include("Books.Editions").AsEnumerable())
      .ToTraceString()
    
    SELECT
      `Project1`.`Id`,
      `Project1`.`Name`,
      `Project1`.`C2` AS `C1`,
      `Project1`.`id1`,
      `Project1`.`AuthorId`,
      `Project1`.`C1` AS `C2`,
      `Project1`.`id2`,
      `Project1`.`Title`
    FROM (SELECT
      `Extent1`.`Id`,
      `Extent1`.`Name`,
      `Join2`.`Id` AS `id1`,
      `Join2`.`AuthorId`,
      `Join2`.`Id` AS `id2`,
      `Join2`.`Title`,
       CASE WHEN (`Join2`.`Id` IS NULL) THEN (NULL)
            WHEN (`Join2`.`BookId` IS NULL) THEN (NULL)
            ELSE (1) END AS `C1`,
       CASE WHEN (`Join2`.`Id` IS NULL) THEN (NULL)
            ELSE (1) END AS `C2`
       FROM `authors` AS `Extent1`
         LEFT OUTER JOIN (SELECT
           `Extent2`.`Id`,
           `Extent2`.`AuthorId`,
           `Join1`.`BookId`,
           `Join1`.`EditionId`,
           `Join1`.`Id` AS `Id1`,
           `Join1`.`Title`
           FROM `books` AS `Extent2`
           LEFT OUTER JOIN (SELECT
             `Extent3`.`BookId`,
             `Extent3`.`EditionId`,
             `Extent4`.`Id`,
             `Extent4`.`Title`
             FROM `editionsinbooks` AS `Extent3`
             INNER JOIN `editions` AS `Extent4`
               ON `Extent4`.`Id` = `Extent3`.`EditionId`) AS `Join1`
           ON `Extent2`.`Id` = `Join1`.`BookId`) AS `Join2`
         ON `Extent1`.`Id` = `Join2`.`AuthorId`) AS `Project1`
       ORDER BY
         `Project1`.`Id` ASC,
         `Project1`.`C2` ASC,
         `Project1`.`id1` ASC,
         `Project1`.`C1` ASC
    
    using (var db = new Db()) {
        var author = db.Authors.Include("Books.Editions").AsEnumerable().First();
        foreach (var book in author.Books)
        {
            foreach (var edition in book.Editions)
            {
                Response.Write(edition.Id + " - " + edition.Title + "<br />");
            }
        }
    }
    
    var sql = ((System.Data.Objects.ObjectQuery)db.Authors.Include("Books.Editions").AsEnumerable().First()).ToTraceString();