如何通过APIController加载时加载OnetoMany字段。
我有一个文章模型
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="
}
]
我建议选择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
);
只需让你的property
虚拟为Lazy Loading
:
public virtual Edition Edition
{
get; set;
}
但是,看看Lazy Loading vs Eager Loading。,看看哪一个适合你的情况。
如果您使用的是延迟加载,请检查Constructor
的DbContext
中是否包含以下语句:
Configuration.LazyLoadingEnabled = true;
Configuration.ProxyCreationEnabled = true;
惰性加载在EF中是一个很好的选择,只要它在正确的位置使用,因为对于每个对象,为了获取它的关系,EF创建一个到数据库的新连接。 另一方面,Eager Loading(Include())在第一个连接中加载列表中的所有相关对象,其中许多是您可能不会使用的。 根据要获取的对象数量,您应该在“延迟加载”和“预先加载”之间进行选择。