Почему при извлечении набора с помощью EFCore извлеченные объекты не включают свои отношения с другими объектами? - PullRequest
0 голосов
/ 09 апреля 2019

При использовании Entity Framework Core с SQL Server я столкнулся с неожиданной проблемой.У меня есть объект A, который имеет отношение «один ко многим» для объекта B.

 [Table("client")]
    public class Client
    {
        public long ID { get; set; }
        public string Name { get; set; }

        public ICollection<Configuration> Configurations { get; set; } = new LinkedList<Configuration>();
    }

Я получаю список экземпляров объекта A из базы данных, например:

public ICollection<Client> GetAllClients()
{
    return _dbContext.Clients.ToList();
}

Когда я вызываю эту функцию, я получаю список экземпляров без экземпляров сущности B в отношениях.Почему объекты в отношениях не извлекаются правильно?

Я также обнаружил, что если я добавлю эту строку кода в функцию, сущности будут извлечены, как и ожидалось.

public ICollection<Client> GetAllClients()
{
    var test = _dbContext.Configurations.ToList();
    return _dbContext.Clients.ToList();
}

Это не имеет смысла для меня.Что мне здесь не хватает?

Ответы [ 2 ]

3 голосов
/ 09 апреля 2019

Вы можете использовать метод Include, чтобы указать связанные данные, которые будут включены в результаты запроса (Eager loading).

Взгляните на следующий пример:

public ICollection<Client> GetAllClients()
{
    return _dbContext.Clients.Include(x => x.Configurations).ToList();
}

Вы можете проверить ссылку MSDN .

0 голосов
/ 09 апреля 2019

Связанные свойства ссылок / коллекций должны загружаться либо явно, либо явно. Как правило, вы хотите загружать, используя Include:

var clients = await _context.Clients.Include(x => x.Configurations).ToListAsync();

В качестве альтернативы, вы можете выполнять отложенную загрузку, но это, как правило, плохая идея, так как это может привести к проблемам с N + 1 запросом (т. Е. Вы выполняете один запрос, а затем отдельный дополнительный запрос для каждого элемента при выполнении итерации, что очевидно крайне неэффективно). Независимо от того, ленивая загрузка требует двух вещей:

  1. Свойство reference / collection должно иметь ключевое слово virtual. EF добавляет функциональность отложенной загрузки, создавая динамический прокси вашего класса сущностей и переопределяя метод получения свойств. Переопределение, конечно, может быть сделано только на виртуальных машинах.

  2. Вы должны явно добавить службы отложенной загрузки:

    services.AddDbContext<MyContext>(o => o.UseLazyLoadingProxies()
        .UseSqlServer(connectionString));
    

Это работает, когда вы запрашиваете конфигурации, потому что EF имеет объект-fixup. Другими словами, он автоматически заполнит связанные свойства ссылки / коллекции, если он ранее уже извлек эти объекты и поместил их в свой кэш объектов. В противном случае, и если вы не загрузите отношения иначе, свойство останется нулевым.

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