Entity Framework включает только возвращающую часть данных базы данных - PullRequest
1 голос
/ 07 марта 2019

Я очень новичок в asp.net и C #, так что терпите меня. Я пытаюсь вернуть данные из базы данных, используя метод Entity Framework .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 Ответ

1 голос
/ 07 марта 2019

Правила рекурсии Serializer будут вызывать это. В основном, как упоминает Йонска, у вас есть круговая ссылка между героем и типом героя. Сериализатор начнется с героя, затем перейдет к сериализации типа героя, который он найдет в коллекции Героя, и рассчитывает на сериализацию, каждый из которых будет ссылаться на тип героя, с коллекциями Героса. Сериализатор выдает ошибку, когда видит это.

Я бы рекомендовал избегать передачи классов 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();

Вы можете использовать Automapper, например, чтобы помочь переводить сущности для просмотра моделей без этого явного кода, используя ProjectTo<TEntity>, который может работать с реализацией IQueryable EF.

  • С большими реалистичными доменами вашему клиенту, вероятно, не понадобится все в графе объектов.
  • Вы не будете предоставлять больше информации, чем вам нужно. (Т.е. видно через средства отладки)
  • Вы получите повышение производительности, если не загрузите весь график или не запустите ленивая загрузка звонков и меньше данных по проводам.

Последний пункт является довольно важным, так как в случае сложных графов объектов SQL может выполнить большую работу, что приведет к гораздо более эффективному запросу, чем загрузка «всего». Ленивые обращения к базе данных могут легко добавить несколько секунд к каждому звонку клиента, и загрузка больших графиков также влияет на память на серверах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...