Как получить доступ к связанной модели без выполнения запроса

Вот что я сейчас делаю:

Class Book{
    ....
    public int authorID { get; set; }
    [ForeignKey("AuthorID")]
    public virtual Author author { get; set; }

}

Из функции, в которой я получаю Book в качестве входных данных. Чтобы получить свойства автора, мне нужно будет вызвать запрос на Author с помощью book.authorID, хотя у меня есть Author как свойство Book.

public string getAuthor (int bookID){
    Book book = _db.Book.where(b => b.id == bookID).SingleOrDefault();
    int authorID = book.authorID;
    Author author = _db.Author.where(a => a.authorID == booking.authorID).SingleOrDefault();
    return author.name;
}

Но я нашел этот код неоправданно длинным, и я подозреваю, что должно быть что-то, что я пропустил, чтобы я не мог получить Author непосредственно из экземпляра книга, например:

public string getAuthor (int bookID){
    Book book = _db.Book.where(b => b.id == bookID).singleOrDefault();
    // anyway to get book.author popuplated by this query?
    return book.author.name;
    //not working. book.author is null 
}

Это вообще возможно?

Как вы ожидаете получить данные, не запрашивая базу данных?

DavidG 20.08.2018 14:52

Привет, Дэвид, спасибо за быстрый ответ. позвольте мне немного изменить пример кода, чтобы я запросил базу данных один раз.

DBSQUARED 20.08.2018 14:55

Кстати, ваш код действительно должен быть более полным. То, что вы опубликовали, не то, что у вас есть Например, singleOrDefault должен быть SingleOrDefault, а что такое booking.authorID?

DavidG 20.08.2018 15:01

@DavidG, он скомпилирован, и предыдущий пример работает. Мне просто нужно было упростить его с тысяч несвязанных кодов и изменить имена переменных на менее чувствительные. Извините за путаницу.

DBSQUARED 20.08.2018 15:23

Что ж, возможно, это сработает, теперь вы исправили код. Но все же что такое booking.authorID?

DavidG 20.08.2018 15:24
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
46
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

In order to retrieve the author properties, I will have to call a query on Author by booking.authorID even though I have Author as a property of Book.

Нет, у тебя этого нет. Вы выполняете вызов API с учетом атрибута [FromBody]. Каждый вызов API начинается без какого-либо контекста предыдущего.

Есть три возможности:

  1. Вы доверяете клиенту предоставить Book.Author в своем запросе POST. Но вы этого не делаете, потому что мы никогда не доверяем вводу пользователя.
  2. Вы запрашиваете информацию из базы данных, используя ввод Book.Id, который вы получаете в запросе POST.
  3. Вы каким-то образом кешируете данные и сначала пытаетесь получить соответствующую информацию из кеша, а если это не удается, повторите # 2.

При этом у книги может быть несколько авторов.

привет, кодекастер, спасибо за быстрый ответ. Я изменил пример кода, чтобы запросить книгу по идентификатору один раз. Итак, это соответствует вашему сценарию №2. Как вы думаете, будет ли указан автор на основе этого запроса?

DBSQUARED 20.08.2018 15:01

Нет, потому что вы не Include(), но это совсем другой вопрос. См. EF Core Docs: загрузка связанных данных. Также действительно помогает, если вы позволите своему вопросу содержать ваш реальный компилируемый код.

CodeCaster 20.08.2018 15:02

О, чувак, я думаю, ты понял. Include () должен быть тем парнем, которого я ищу. Позвольте мне проверить это. Спасибо.

DBSQUARED 20.08.2018 15:06

Как бы то ни было, поскольку Author является виртуальным, при условии, что вы используете EF Core 2.1+, Author будет загружен автоматически при первой попытке доступа к нему. Тем не менее, все же предпочтительнее загружать его через Include.

Chris Pratt 20.08.2018 15:14

Спасибо @ChrisPratt. 2.0 на самом деле, все еще пытаюсь многому научиться. Как вы думаете, вы имеете в виду Author под authorID или просто модель Author в целом? Наверное, первое.

DBSQUARED 20.08.2018 15:21

@DBSQUARED 2.0 не имеет ленивой загрузки, вам нужно использовать Include

DavidG 20.08.2018 15:25

EF Core 2.1 теперь поддерживает отложенную загрузку. Поэтому, когда вы пытаетесь получить доступ к свойству Author, EF автоматически отправляет запрос автору и загружает данные. Это предполагает, что ваше свойство является виртуальным, поскольку логика отложенной загрузки добавляется путем переопределения свойства в производном прокси-классе в памяти, и свойство не может быть переопределено, если оно не виртуальное. Однако, если вы все еще используете 2.0, который не поддерживает отложенную загрузку, ключевое слово virtual ничего не делает и не нужно.

Chris Pratt 20.08.2018 15:25

Другие вопросы по теме