Вот что я сейчас делаю:
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
}
Это вообще возможно?
Привет, Дэвид, спасибо за быстрый ответ. позвольте мне немного изменить пример кода, чтобы я запросил базу данных один раз.
Кстати, ваш код действительно должен быть более полным. То, что вы опубликовали, не то, что у вас есть Например, singleOrDefault должен быть SingleOrDefault, а что такое booking.authorID?
@DavidG, он скомпилирован, и предыдущий пример работает. Мне просто нужно было упростить его с тысяч несвязанных кодов и изменить имена переменных на менее чувствительные. Извините за путаницу.
Что ж, возможно, это сработает, теперь вы исправили код. Но все же что такое booking.authorID?





In order to retrieve the author properties, I will have to call a query on Author by booking.authorID even though I have
Authoras a property ofBook.
Нет, у тебя этого нет. Вы выполняете вызов API с учетом атрибута [FromBody]. Каждый вызов API начинается без какого-либо контекста предыдущего.
Есть три возможности:
Book.Author в своем запросе POST. Но вы этого не делаете, потому что мы никогда не доверяем вводу пользователя.Book.Id, который вы получаете в запросе POST.При этом у книги может быть несколько авторов.
привет, кодекастер, спасибо за быстрый ответ. Я изменил пример кода, чтобы запросить книгу по идентификатору один раз. Итак, это соответствует вашему сценарию №2. Как вы думаете, будет ли указан автор на основе этого запроса?
Нет, потому что вы не Include(), но это совсем другой вопрос. См. EF Core Docs: загрузка связанных данных. Также действительно помогает, если вы позволите своему вопросу содержать ваш реальный компилируемый код.
О, чувак, я думаю, ты понял. Include () должен быть тем парнем, которого я ищу. Позвольте мне проверить это. Спасибо.
Как бы то ни было, поскольку Author является виртуальным, при условии, что вы используете EF Core 2.1+, Author будет загружен автоматически при первой попытке доступа к нему. Тем не менее, все же предпочтительнее загружать его через Include.
Спасибо @ChrisPratt. 2.0 на самом деле, все еще пытаюсь многому научиться. Как вы думаете, вы имеете в виду Author под authorID или просто модель Author в целом? Наверное, первое.
@DBSQUARED 2.0 не имеет ленивой загрузки, вам нужно использовать Include
EF Core 2.1 теперь поддерживает отложенную загрузку. Поэтому, когда вы пытаетесь получить доступ к свойству Author, EF автоматически отправляет запрос автору и загружает данные. Это предполагает, что ваше свойство является виртуальным, поскольку логика отложенной загрузки добавляется путем переопределения свойства в производном прокси-классе в памяти, и свойство не может быть переопределено, если оно не виртуальное. Однако, если вы все еще используете 2.0, который не поддерживает отложенную загрузку, ключевое слово virtual ничего не делает и не нужно.
Как вы ожидаете получить данные, не запрашивая базу данных?