Linq net核心API控制器返回不完整的json
几天前,我问了一个关于我正在制作的一款使用实体框架的网络核心游戏的问题 我有一个问题,控制器返回重复的JSON数据 根据其中一个答案,我将控制器更改为:Linq net核心API控制器返回不完整的json,linq,asp.net-core,entity-framework-core,asp.net-core-webapi,Linq,Asp.net Core,Entity Framework Core,Asp.net Core Webapi,几天前,我问了一个关于我正在制作的一款使用实体框架的网络核心游戏的问题 我有一个问题,控制器返回重复的JSON数据 根据其中一个答案,我将控制器更改为: [HttpGet("GetDungeonAndRoomData/{dungeonId}")] public async Task<ActionResult<GameDungeon>> GetDungeonAndRoomData(Guid dungeonID) { { var dungeon = a
[HttpGet("GetDungeonAndRoomData/{dungeonId}")]
public async Task<ActionResult<GameDungeon>> GetDungeonAndRoomData(Guid dungeonID)
{
{
var dungeon = await _context.DungeonList
.Select(c => new GameDungeon
{
DungeonId = c.DungeonId,
DungeonName = c.DungeonName,
StartRoom = c.StartRoom,
Rooms = c.Rooms.Select(n => new GameDungeonRoom
{
RoomId = n.RoomId,
RoomText = n.RoomText,
TreasureId = n.TreasureId
})
}).SingleOrDefaultAsync(c => c.DungeonId == dungeonID);
建造和运行游戏,我现在得到一组地下城数据,但它不会返回任何房间
首先,基于这个堆栈溢出问题,我认为这是因为我需要将它添加到Startup.cs文件中:
services.AddMvc()
.AddJsonOptions(
options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
但事实并非如此
于是我花了一晚上的时间尝试了一系列不同的方法来编写控制器,但是它们要么产生了相同的结果,要么只是抛出了一个错误
今天早上查看代码时,我意识到了一些事情。在我的控制器中,创建新“GameDungeon”的第一个select语句是从_context.DungeonList获取数据
DungeonList是实体框架从我的数据库中的真实表生成的模型
但游戏地下城只是我创建的一个新的类模型。它基于我数据库中一个名为RoomList的表,但在U上下文中没有专门处理GameDungeonRoom的内容
所以我想知道,我是否应该引入另一个类似这样的控制器
var rooms = await _context.RoomList
.Select(c => new GameDungeonRoom ...
然后以某种方式将其附加到GameDungeon对象
午饭后我尝试了一下,但结果只是创建了一堆代码,造成了更大的错误,所以我把它全部删除了
无论如何,在所有这些之后,这就是我的JSON目前所处的位置:
{
"dungeonId" : "293hf938",
"dungeonName" : "Dungeon of Dread",
"startRoom" : "bjgh39811ffr",
"roomId" : "fgf4h635j",
"roomText" : "A big empty room",
"treasureId" : "12a",
"rooms": [
你会注意到“房间”是空的。我不太清楚为什么会这样,或者发生了什么
我的一个想法是,也许我应该创建一个API控制器来获取特定地下城的地下城数据。然后创建另一个API控制器,用于获取特定地下城的房间数据
然后让客户端调用两个控制器(使用相同的地下城ID)并在客户端合并数据
所以我想知道是否有人能想出一个办法来解释为什么“房间”对象是空的
谢谢 只是猜测由于缓存了数据上下文,您可能在结果集中遇到了循环引用。因此,Json序列化程序无法正确序列化它并提供不完整的Json内容。所以你们可以试着用下面的方法来说明这一点
var dungeon = await _context.DungeonList
.Select(c => new GameDungeon
{
DungeonId = c.DungeonId,
DungeonName = c.DungeonName,
StartRoom = c.StartRoom,
Rooms = c.Rooms.Select(n => new GameDungeonRoom
{
RoomId = n.RoomId,
RoomText = n.RoomText,
TreasureId = n.TreasureId
})
})
.AsNoTracking() //This ignore the cached data
.SingleOrDefaultAsync(c => c.DungeonId == dungeonID);
您是否已更改查询以返回房间?如果您不告诉实体,实体通常不知道如何获取关联数据。@我在控制器中的computercarguy是这样做的……但我想知道是否需要在其他地方这样做。如果您使用从查询到JSON返回到客户端的同一模型,则不必修改任何内容。您可能需要修改客户端模型以正确接收它,但是如果JSON是传输到客户端的(通过Fiddler或查看浏览器控制台中的网络流量找到的),那么您需要验证是否正确查询了房间。要么它没有得到数据,要么它没有被正确地插入到你的
游戏地下室
模型中。我觉得你需要把你的钥匙
移动到地下城ID
并放入[ForeignKey(“游戏地下城”))
。如果我的最后一条评论恰好是答案,我可以把它做成一个答案,这样它就可以被投票和/或接受。嗨@computercarguy,我不确定我是否理解你的评论。所以也许我应该给我的GameDungeroom类添加一个外键?谢谢Wijitha,添加.AsNoTracking()产生了相同的结果。@SkyeBoniwell,在返回数据之前,您是否可以调试并检查对象中的内容。然后执行Newtosoft.Json.Serialize(地下城)。查看您的结果是否可以成功转换为Jason。还可以检查您是否在DB上下文中设置了急切加载。如何启用急切加载?谢谢
{
"dungeonId" : "293hf938",
"dungeonName" : "Dungeon of Dread",
"startRoom" : "bjgh39811ffr",
"roomId" : "fgf4h635j",
"roomText" : "A big empty room",
"treasureId" : "12a",
"rooms": [
var dungeon = await _context.DungeonList
.Select(c => new GameDungeon
{
DungeonId = c.DungeonId,
DungeonName = c.DungeonName,
StartRoom = c.StartRoom,
Rooms = c.Rooms.Select(n => new GameDungeonRoom
{
RoomId = n.RoomId,
RoomText = n.RoomText,
TreasureId = n.TreasureId
})
})
.AsNoTracking() //This ignore the cached data
.SingleOrDefaultAsync(c => c.DungeonId == dungeonID);