如何加载 OneToMany 关系中的字段?

How to load fields in a OneToMany relation?

如何在通过 APIController 加载时加载 OnetoMany Field。

我有文章模型

public class Article : BaseEntity
{

    public string Title
    {
        get; set;
    }

    public Edition Edition
    {
        get; set;
    }

}

还有一个版本模型

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="
    }
]

只需将 property 虚拟化为 Lazy Loading:

public virtual Edition Edition
{
    get; set;
}

不过,请看一下 ,看看哪一个适合您的情况。

更新:

如果您正在使用延迟加载,请检查您的 DbContextConstructor 中是否包含以下语句:

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

延迟加载在 EF 中是一个不错的选择,只要用在正确的地方,因为对于每个对象,为了获取其关系,EF 会创建一个新的数据库连接。
另一方面,Eager Loading (Include()) 在第一次连接时加载列表中的所有相关对象,其中许多您可能不会使用。
根据要获取的对象数量,您应该在 Lazy Loading 和 Eager Loading 之间进行选择。

我建议采用 EF Core 提供的简单解决方案,即每次调用特定数据的数据访问层时添加 .Include(x=>x.ReferenceIWantToLoad)。 这避免了在项目模型中将关键字 'virtual' 添加到每个外国参考文献中的任何重组,例如:

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

PS:为了能够忽略引用的无限循环,您希望将其添加到您的启动文件配置中:

services.AddMvc()
        .AddJsonOptions(
            options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
        );