C# LINQ到实体的奇怪行为包括
我意识到我不完全理解LINQ to Entities中的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
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();