Entity framework EntityFramework核心延迟加载返回所有相关表

Entity framework EntityFramework核心延迟加载返回所有相关表,entity-framework,lazy-loading,Entity Framework,Lazy Loading,我的数据库中有3个表: 国家 州 城市 我有一个API,应该返回一个国家及其州 然而,当我尝试这样做时,我最终得到一个JSON对象,其中包含国家、其统计数据以及每个州下的所有城市 我的代码是这样的(急切和懒惰都返回相同的结果): 我怎么能只把国家装进州里而离开城市呢?我的建议是永远不要返回实体。实体应该只存在于作为数据模型表示的DbContext中。视图或API使用的模型有不同的用途,应该是EF可以填充的简单、可序列化的POCO。这使它们完全适合您的视图/消费者所关心的数据。在你的情况下,你只关

我的数据库中有3个表: 国家 州 城市

我有一个API,应该返回一个国家及其州

然而,当我尝试这样做时,我最终得到一个JSON对象,其中包含国家、其统计数据以及每个州下的所有城市

我的代码是这样的(急切和懒惰都返回相同的结果):


我怎么能只把国家装进州里而离开城市呢?

我的建议是永远不要返回实体。实体应该只存在于作为数据模型表示的DbContext中。视图或API使用的模型有不同的用途,应该是EF可以填充的简单、可序列化的POCO。这使它们完全适合您的视图/消费者所关心的数据。在你的情况下,你只关心国家和州,而不关心城市或其他相关部分。您甚至可能不需要关于一个国家或州的所有数据。让EF为所需的数据构建一个查询。这将提高查询的性能,减少服务器和客户端上的内存使用,并避免序列化带来的陷阱。(即循环引用)实体应始终代表实体的完整状态。关闭延迟加载并传递不完整的实体图很容易导致错误,因为接受对实体的引用并面对空/空引用的方法将不知道该引用是否只是未加载或不存在

[Serializable]
public class CountryViewModel
{
    public int CountryID { get; set; }
    public string CountryName { get; set; }
    public IEnumerable<StateViewModel> States { get; set; } = new List<StateViewModel>();
}

[Serializable]
public class StateViewModel
{
    public int StateID { get; set; }
    public string StateName { get; set; }
}
利用Automapper,这可以相当容易地简化为:

var countries = await _context.Countries
    .ProjectTo<CountryViewModel>()
    .ToListAsync(cancellationToken);
var countries=wait\u context.countries
.ProjectTo()
.ToListSync(取消令牌);

关闭延迟加载。否则JSON序列化程序将遍历对象图并触发延迟加载。感谢您的指导。我实施了类似的方法,避免发回整个实体及其相关实体。我使用AutoMapper库发回了最小的DTO,并提供了前端所需的数据。
var countries = await _context.Countries
    .Select(x => new CountryViewModel
    {
        CountryId = x.CountryId,
        CountryName = x.Name,
        States = x.States.Select(s => new StateViewModel
        {
            StateId = s.StateId,
            StateName = s.Name
        }).ToList()
    }).ToListAsync(cancellationToken);
var countries = await _context.Countries
    .ProjectTo<CountryViewModel>()
    .ToListAsync(cancellationToken);