如何加载 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;
}
不过,请看一下 ,看看哪一个适合您的情况。
更新:
如果您正在使用延迟加载,请检查您的 DbContext
的 Constructor
中是否包含以下语句:
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
);
如何在通过 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;
}
不过,请看一下
更新:
如果您正在使用延迟加载,请检查您的 DbContext
的 Constructor
中是否包含以下语句:
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
);