实体框架仅包含返回的部分数据库数据

时间:2019-03-07 01:41:06

标签: c# entity-framework asp.net-core

我对asp.net和C#非常陌生,所以请多多包涵。我试图使用实体框架.include()方法从数据库返回数据,以便可以从另一个表中获取外键信息。但是,返回的只是数据的一部分。它似乎在一切返回之前就被切断了。

"[{"id":11,"name":"Mr. Not-so-Nice","heroType":3,"heroTypeNavigation":{"id":3,"type":"Villian","heroes":["

这给了我错误:SyntaxError:JSON输入意外结束。

对于返回的模型类和控制器的GET部分,请看下面。如果删除“ include()”方法,它将从主表中返回所有英雄。

public partial class Hero
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? HeroType { get; set; }

    public virtual HeroTypes HeroTypeNavigation { get; set; }
}

{
public partial class HeroTypes
{
    public HeroTypes()
    {
        Heroes = new HashSet<Hero>();
    }

    public int Id { get; set; }
    public string Type { get; set; }

    public virtual ICollection<Hero> Heroes { get; set; }
}

// GET: api/Heroes
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Hero>>> GetHeroesTable()
    {
        return await _context.HeroesTable.Include(hero => hero.HeroTypeNavigation).ToListAsync();   
    }

1 个答案:

答案 0 :(得分:1)

Serializer递归规则将使其失效。基本上如jonsca所述,您在hero和hero类型之间有一个循环引用。序列化程序将以英雄开始,然后去序列化英雄类型,它将找到英雄的收藏并期望进行序列化,每个序列都将参考英雄类型,并带有英雄集合。 / p>

我建议避免将Entity类传递回视图,以避免EF和延迟加载的问题。序列化将遍历属性,这将触发延迟加载。为避免这种情况,请为视图所需的细节构建视图模型,并根据需要展平。

例如,如果您要显示英雄列表及其类型:

public class HeroViewModel
{
    public int HeroId { get; set; }
    public string Name { get; set; }
    public string HeroType { get; set; }
}

加载:

var heroes = await _context.HeroesTable.Select(x => new HeroViewModel
{
    HeroId = x.HeroId,
    Name = x.Name,
    HeroType = x.HeroType.Type
}).ToListAsync();

例如,您可以利用ProjectTo<TEntity>来利用Automapper来帮助实体转换模型以查看模型,而无需使用显式代码,该IQueryable可以与EF的read实现一起使用。

  • 使用较大的现实域,您的客户可能不需要对象图中的所有内容。
  • 您不会暴露比您需要更多的信息。 (即通过调试工具可见)
  • 通过不加载整个图形或触发来提高性能 延迟加载调用,并且在线上的数据更少。

最后一点是非常重要的一点,因为对于复杂的对象图,SQL可以完成很多工作,从而导致查询比加载“所有内容”更有效。延迟访问数据库可以很容易地使客户端的每个调用增加几秒钟的时间,并且加载大图也会对服务器产生内存影响。