繁体   English   中英

EF Core 导航属性自行加载

[英]EF Core navigation properties loads itself

我的 DB_Context 中有以下类作为实体。

public class Glossary
{
    #region Properties
    public Guid GlossaryId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }


    #region NavigationProperties
    public virtual ICollection<Item> Items { get; set; }
    #endregion
}
public class Item
{
    #region Properties
    public Guid ItemId { get; set; }
    public string Name { get; set; }
    public string Definition { get; set; }

    #region ForeignKeys
    public Guid GlossaryId { get; set; }
    #endregion
    #endregion

    #region Navigation Properties
    public virtual Glossary Glossary { get; set; }
    #endregion
}

当我尝试使用词汇表类型的实体的项目

public async Task<IEnumerable<Glossary>> Get()
    {
        return await _context.Glossaries
                    .Include(x => x.Items)
                    .OrderBy(x => x.CreatedAt)
                    .ToListAsync();
    }

我从我的 API 得到以下 JSOn:

{
    "glossaryId": "674c1358-861b-11ea-9370-e45a1762a61b",
    "name": "Test1",
    "description": "Description of Test1",
    "items": [
        {
            "itemId": "f2847601-86db-11ea-9370-e45a1762a61b",
            "name": "TestItem",
            "definition": "TestDefinition",
            "glossaryId": "674c1358-861b-11ea-9370-e45a1762a61b",
            "glossary": {
                "glossaryId": "674c1358-861b-11ea-9370-e45a1762a61b",
                "name": "Test1",
                "description": "Description of Test1",
                "items": []
            }
        }
    ]
}

我的问题是,词汇表的项目也包括它的词汇表,我不想要。

有什么方法可以只包含一个导航属性而不再次包含相同的导航属性?

为了避免这个问题,在每个项目中,我总是使用 DTO 和 Automapper。 通常,从来没有必要按原样归还数据库 model:只提供解决功能所需的内容。 在您的情况下,您需要归还所有词汇表。

在您的情况下,我会介绍 Automapper。 在您的 Net.Core 项目上安装Automapper后,我将创建 2 个 DTO,称为:

public class GlossaryDto : ICustomMapping

    public Guid GlossaryId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }      

    public ICollection<ItemDto> Items { get; set; }

    public void CreateMappings(Profile configuration)
    {
        configuration.CreateMap<Glossary, GlossaryDto>();
    }

public class ItemDto  : ICustomMapping
{
    public Guid ItemId { get; set; }
    public string Name { get; set; }
    public string Definition { get; set; }

    public Guid GlossaryId { get; set; }

    public void CreateMappings(Profile configuration)
    {
        configuration.CreateMap<Item, ItemDto>();
    }

}

现在您可以简单地重写您的 Get 以返回 Dto 而不是数据库 model(实体):

public async Task<IEnumerable<GlossaryDto>> Get()
    {
        var result = await _context.Glossaries
                    .Include(x => x.Items)
                    .OrderBy(x => x.CreatedAt)
                    .ToListAsync()
        return await mapper.Map<IEnumerable<GlossaryDto>(result);
    }

通过这种方式,我们从 Dto 中删除了循环引用,您不会有任何问题:由于 ItemDto 没有 GlossaryDto 的“导航”属性,因此链已正确关闭。 您的 JSON 拥有所有必要的信息。 将来,如果您需要返回带有 GlossaryDto 导航属性的 ItemDto,请创建一个具有不同名称的新属性。 您还可以创建一个等于数据库 Model 的 DTO,然后通过指定MaxDepth()使用自动映射器“剪切”循环引用,但我更喜欢为真正需要的内容创建特定的 DTO。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM