EF6 Linq 查询。仅包括返回子表的第一个条目
Posted
技术标签:
【中文标题】EF6 Linq 查询。仅包括返回子表的第一个条目【英文标题】:EF6 Linq Query .Include only returning first entry of child table 【发布时间】:2017-04-15 06:34:58 【问题描述】:我想检索给定口袋妖怪的遭遇列表,因为口袋妖怪可以在很多地方遇到,所以我一直在尝试许多变体
var currentPokemon = _context.Pokemon
.Where(mon => mon.Id == id)
.Include(mon => mon.Encounters)
.FirstOrDefault();
结果是一个包含所有相关数据的口袋妖怪对象,但只有第一次遭遇被检索并放入一个集合中,结果如下:
查看数据库,大约有 20 次与毛毛虫的遭遇,我想访问所有这些,但只能获得一个。
Pokemon 类的样子(省略不相关的字段):
[Table("pokemon")]
public partial class Pokemon
public Pokemon()
Encounters = new HashSet<Encounters>();
[Column("id")]
public long Id get; set;
[Required]
[Column("identifier", TypeName = "VARCHAR(79)")]
public string Identifier get; set;
.
.
.
[InverseProperty("Pokemon")]
public virtual ICollection<Encounters> Encounters get; set;
邂逅是什么样子的:
public partial class Encounters
.
.
.
[ForeignKey("PokemonId")]
[InverseProperty("Encounters")]
public virtual Pokemon Pokemon get; set;
数据库数据:
我在这里误会了什么?
【问题讨论】:
生成的sql是什么?上网看看如何获取sql查询 你能显示db的记录吗?你指的是正确的数据库吗? @sampath i.imgur.com/s9N7WyP.png 您指的数据库是否正确? 我无法使用全新的 DbContext 和最少的数据重现此行为。我按预期得到了口袋妖怪和遭遇。您未显示的代码中必须有其他内容。您发布的代码是可以的,并且您执行操作的顺序虽然不是最佳的,但确实会生成相同的 sql。 【参考方案1】:我想是因为你打电话给.FirstOrDefault()
,它只得到第一个项目。你可以省略它并添加.ToList()
吗?此外,var currentPokemon
似乎不是一个好的变量名。你说你想要一个遭遇列表,对吧? var pokemonEncounters
呢?
【讨论】:
首先或默认将在口袋妖怪结果上完成,而不是遭遇 弗雷杜所说的。省略.FirstOrDefault()
只会返回一个长度为 1 的口袋妖怪数组,这是没有意义的,因为我只想得到 1 个口袋妖怪。至于我在寻找什么,这是一个单独的口袋妖怪,其中列出了该口袋妖怪的所有相关遭遇。用简单的英语,我想问“谁是 pokemon #10”并得到“Pokemon 10 是 Caterpie,你可以在以下地方找到 Caterpie:(地点列表)。”在最后添加.ToList()
会导致遭遇列表,但没有口袋妖怪。
怎么样 var currentPokemon = _context.Pokemon .Where(mon => mon.Id == id) .Include(mon => mon.Encounters) .FirstOrDefault().Select(p => p .遭遇);
你不能在.FirstOrDefault()
返回的口袋妖怪对象上调用.Select()
@Fredou 和@Riwen - 你是对的。现在我想起来了,var currentPokemon = _context.Pokemon.Include(mon => mon.Encounters).FirstOrDefault(p => p.Id = id);
应该返回第一个带有遭遇列表的口袋妖怪。您应该能够使用currentPokemon.Encounters
访问遭遇。对吗?【参考方案2】:
我认为问题在于您使用 ForeignKey 和 InverseProperty 设置关系的方式。
尝试重写为:
[Table("Pokemon")]
public class Pokemon
public int Id get; set;
public string Name get; set;
[InverseProperty("Pokemon")]
public ICollection<Encounter> Encounters get; set;
[Table("Enconters")]
public class Encounter
public int Id get; set;
public int PokemonId get; set;
[ForeignKey("PokemonId")]
public Pokemon Pokemon get; set;
【讨论】:
【参考方案3】:抱歉,我一直在寻找错误的地方来寻找答案。在调试器中逐步完成后,我可以看到我的 Pokemon 查询确实返回了所需的结果:附加了许多遭遇的 pokemon。我的问题似乎出在其他地方(特别是:我看到的 JSON 化对象通过我的 Web 前端截断了遇到数组以仅包含第一个结果)。
我将发布一个包含正确问题的新问题,并在发现问题后从此处链接到该问题。
【讨论】:
是的,在输出中发现一个 json 序列化错误。 好的,所以问题是 JSON 序列化程序检测到自引用循环(因为 Pokemon 引用了 Encounters,而 Encounters 又引用了 pokemon)并在 Debug 输出中抛出了一个错误(我错过了重复)以避免进入无限循环。这个问题的解决方案在这里:***.com/questions/17313632/…以上是关于EF6 Linq 查询。仅包括返回子表的第一个条目的主要内容,如果未能解决你的问题,请参考以下文章