gpt4 book ai didi

c# - 如何仅使用数据库中的 Entity Framework 脚手架模型

转载 作者:太空宇宙 更新时间:2023-11-03 19:42:52 34 4
gpt4 key购买 nike

我一直在使用 .Net Core Entity Framework 数据库优先方法和脚手架技术。

它从我的数据库表中为我生成了几个模型/类,但现在,我将尽量减少我对这两个表的问题......两个 ChampionID 列上的一对多关系:

enter image description here

因此,在使用 EntityCore 工具构建/映射模型后,它生成了以下两个类(以及其他几个不相关的类):

冠军.cs:

public partial class Champion
{
public Champion()
{
ChampionScreenshot = new HashSet<ChampionScreenshot>();
ChampionUser = new HashSet<ChampionUser>();
ChampionUserRate = new HashSet<ChampionUserRate>();
}

public int ChampionId { get; set; }
public string Name { get; set; }
public string Nickname { get; set; }
public string Description { get; set; }
public string ImagePath { get; set; }
public byte AttackDamageScore { get; set; }
public byte AbilityPowerScore { get; set; }
public byte ResistanceScore { get; set; }
public byte PlayingDifficult { get; set; }
public int PrimaryClassId { get; set; }
public int SecondaryClassId { get; set; }

public ChampionClass PrimaryClass { get; set; }
public ChampionClass SecondaryClass { get; set; }
public ICollection<ChampionScreenshot> ChampionScreenshot { get; set; }
public ICollection<ChampionUser> ChampionUser { get; set; }
public ICollection<ChampionUserRate> ChampionUserRate { get; set; }
}

ChampionScreenshot.cs:

public partial class ChampionScreenshot
{
public int ChampionScreenshotId { get; set; }
public string ImagePath { get; set; }
public int ChampionId { get; set; }

public Champion Champion { get; set; }
}

我的疑问是:检索填充了 ChampionScreenshot 属性的 Champion 对象的正确方法是什么?

例如,这是我在服务层中所做的:

    public async Task<Champion> GetChampion(int id)
{
Champion champion = await _context.Champion.FirstAsync(m => m.ChampionId == id);
champion.ChampionScreenshot = _context.ChampionScreenshot.ToListAsync().Result.FindAll(m => m.ChampionId == champion.ChampionId);

return champion;
}

所以我基本上得到了一个特定的 Champion,然后分别填充 ChampionScreenshot 属性(这也是一个类),但问题是在我的 ChampionScreenshot 中还有一个 Champion 类属性,它再次完全加载:

enter image description here

一旦暴露在 Restful 服务的端点中,显然会产生错误:

[Produces("application/json")]
[Route("api/Champions")]
public class ChampionsController : Controller
{
[HttpGet("{id}")]
public async Task<IActionResult> GetChampion([FromRoute] int id)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

var champion = await _service.GetChampion(id);

if (champion == null)
{
return NotFound();
}
return Ok(champion);
}
...

错误:

Newtonsoft.Json.JsonSerializationException: Self referencing loop detected for property 'champion' with type 'ChampionsService.Models.Champion'. Path 'championScreenshot[0]'. 

所以,我想只是创建我的自定义模型并用从我的 DbContext 中提取的数据填充它,而不是返回已经创建的模型,但我真的认为应该有一种方法可以完全使用映射的模型,我想知道...

最佳答案

Champion 引用自身:

Champion > 多个ChampionScreenshot > Champion(回到原来的对象)

这很容易解决:

return Json(champion, new JsonSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore });

或者您可以对整个应用程序执行此操作:

services.AddMvc().AddJsonOptions(opts => 
{
opts.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});

然后就是:

return Json(champion);

不过,以下问题让我很困扰:

Champion champion = await _context.Champion.FirstAsync(m => m.ChampionId == id);
champion.ChampionScreenshot = _context.ChampionScreenshot.ToListAsync().Result.FindAll(m => m.ChampionId == champion.ChampionId);

你是说“去数据库,下载每一个冠军截图,然后通过内存搜索找到我想要的”。这不仅速度非常慢,而且还会浪费您的应用程序和数据库中的大量资源。要包含数据,您可以使用 Include:

Champion champion = await _context.Champion
.Include(x => x.ChampionScreenshot)
.FirstAsync(x => x.ChampionId == id);

(这表示“转到数据库并给我带来冠军,但也包括所有对应的 ChampionScreenshot,通过内部连接)。

关于c# - 如何仅使用数据库中的 Entity Framework 脚手架模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50457424/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com