Как загрузить поля в отношении OneToMany? - PullRequest
0 голосов
/ 26 февраля 2019

Как загрузить поле OnetoMany при загрузке через APIController.

У меня есть модель Article

public class Article : BaseEntity
{

    public string Title
    {
        get; set;
    }

    public Edition Edition
    {
        get; set;
    }

}

и модель Edition

public class Edition : BaseEntity
{
    public string Title
    {
        get; set;
    }

    public int Position { get; set; }

}

Модель BaseEntityвыглядит так:

public class BaseEntity
{
    public Guid ID { get; set; }

    [Timestamp]
    public byte[] Timestamp { get; set; }

    public BaseEntity()
    {
        ID = Guid.NewGuid();
    }
}

Я определил функцию HttpGet в моем контроллере статей, куда я хочу загрузить все свои статьи.

[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesDefaultResponseType]
public ActionResult<IEnumerable<Article>> GetArticles([FromRoute] Guid editionId)
{
    return Ok(_context.Articles);
}

К сожалению, EditionId не загружается с другимиполя.Вот как выглядит JSON:

[
    {
        "title": "Article Postman",
        "edition": null,
        "id": "74b53ba7-75a4-46c6-a70f-470e73c83ee5",
        "timestamp": "AAAAAAAAB+M="
    },
    {
        "title": "Title",
        "edition": null,
        "id": "d74b4ac3-7ddc-4c89-bd74-4fbe3fbe0cd8",
        "timestamp": "AAAAAAAAB+E="
    },
    {
        "title": "Article Postman 2",
        "edition": null,
        "id": "5dddd99f-151a-4325-91f7-c8295b872410",
        "timestamp": "AAAAAAAAB+U="
    }
]

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Я бы предложил перейти к простому решению, предлагаемому EF Core, которое каждый раз, когда вы называете вас слоем доступа к данным, для определенных данных вы добавляете .Include (x => x.ReferenceIWantToLoad).Это позволяет избежать какой-либо реструктуризации в моделях проекта, чтобы добавить ключевое слово «виртуальный» к каждой внешней ссылке, например:

var allArticlesWithEditions = await _dbContext.Articles.Include(x=>x.Edition).ToListAsync();

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

services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );
0 голосов
/ 26 февраля 2019

Просто сделайте ваш property виртуальным для Lazy Loading:

public virtual Edition Edition
{
    get; set;
}

Однако взгляните на Ленивая загрузка против готовой загрузки ., Чтобы увидеть, какой из них подходит вашему случаю.

Обновление:

Если вы используете отложенную загрузку, проверьте, чтобы в Constructor вашего DbContext были указаны следующие операторы:

Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = true;

Ленивая загрузкаЭто хороший вариант в EF, поскольку он используется в нужном месте, потому что для каждого объекта, для извлечения его отношения, EF создает новое соединение с базой данных.
С другой стороны, Eager Loading (Include ()) загружает все связанные объекты вашего списка при первом подключении, многие из которых вы, вероятно, не будете использовать.
В зависимости от количества объектов, которые нужно выбрать, вы должны выбрать между Lazy Loading и Eager Loading.

...