获取具有深层次相关实体的对象 [英] Get Object with deep level of related entity

查看:64
本文介绍了获取具有深层次相关实体的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个具有一对一关系的实体类,如下所示:

Suppose I have a entity class with one to one relationship as below:

public class Transaction
{
    public int TransactionID { get; set; }
    public Double Amount { get; set; }
    public int TransactionDetailID { get; set; }

    public virtual TransactionDetail TransactionDetailFk { get; set; }
}
public class TransactionDetail
{
    public int TransactionDetailID { get; set; }
    public DateTime PostedDate { get; set; }
    public int TransactionTypeID { get; set; }
    public int TransactionCategoryID { get; set; }
    public int PaymentMethodID { get; set; }
    public int PaymentPayorID { get; set; }

    public virtual TransactionType TransactionTypeFk { get; set; }
    public virtual TransactionCategory TransactionCategoryFk { get; set; }
    public virtual PaymentMethod PaymentMethodFk { get; set; }
    public virtual PaymentPayor PaymentPayorFk { get; set; }
    public virtual Transaction TransactionFk { get; set; }
}

现在,我想获得一个基于TransactionID的事务对象我想将我所有的相关对象从Transaction到TransactionDetail
传递给(TransactionType / TransactionCategory / PaymentMethod / PaymentPayor),这是一个两层数据映射,我的函数将是:

Now I would like to get a Transaction Object based on TransactionID, in addition I would like to get all my related object from Transaction to TransactionDetail to (TransactionType/TransactionCategory/PaymentMethod/PaymentPayor), which is a two-level data mapping and my function would be like:

public async Task<Transaction> GetSingleFullTransactionByIDAsync(int transactionID)
    => await GetSingleOrDefaultAsync(
            predicate: tr => (tr.TransactionID == transactionID),
            include: (obj => (
                            obj
                            .Include(entity => entity.TransactionDetailFk)
                                .ThenInclude(td => td.PaymentPayorFk)
                            .Include(entity => entity.TransactionDetailFk)
                                .ThenInclude(td => td.PaymentMethodFk)
                            .Include(entity => entity.TransactionDetailFk)
                                .ThenInclude(td => td.TransactionTypeFk)
                            .Include(entity => entity.TransactionDetailFk)
                                .ThenInclude(td => td.TransactionCategoryFk)
                    ))
        );

我觉得我的代码不是那么干净整洁,因为对于交易明细的每个相关实体,我实际上是包含事务细节的多个实例...我想做以下类似的事情,其中​​仅包含事务细节的一个实例,但是实体框架不允许我这样做:

I feel my code is not that clean and tidy, since for each related entity of Transaction Detail, I am actually including multiple instance of transaction detail...I would like to do something like below which only include one instance of Transaction Detail but entity framework does not allow me to do that:

public async Task<Transaction> GetSingleFullTransactionByIDAsync(int transactionID)
    => await GetSingleOrDefaultAsync(
            predicate: tr => (tr.TransactionID == transactionID),
            include: (obj => (
                            obj
                            .Include(entity => entity.TransactionDetailFk)
                                .ThenInclude(td => td.PaymentPayorFk)
                                .ThenInclude(td => td.PaymentMethodFk)
                                .ThenInclude(td => td.TransactionTypeFk)
                                .ThenInclude(td => td.TransactionCategoryFk)
                    ))
        );

那么使用EF内核实现此目的的有效方法是什么?注意这里我使用的是存储库模式,所以我不能使用sql-to-linq表达式,而只需要使用 Include / ThenInclude操作...

So what would be the efficient way for doing that using EF core? Note here I am using repository pattern so I can't use sql-to-linq expression, but only have to use "Include"/"ThenInclude" operation...

推荐答案


我觉得我的代码不是那么干净整洁,因为对于交易明细的每个相关实体,我实际上包括了交易明细的多个实例...

I feel my code is not that clean and tidy, since for each related entity of Transaction Detail, I am actually including multiple instance of transaction detail...

这正是在EF Core中包括多个相关实体的预期(通过设计)方式。在加载相关数据-包括EF Core文档的多个级别部分:

This is exactly the intended ("by design")way of including multiple related entities in EF Core. It is explained (with example) in the Loading Related Data - Including multiple levels section of the EF Core documentation:


您可能希望包括多个相关实体被包含的实体之一。例如,查询博客时,您要包含帖子,然后要同时包含帖子的作者和标签。为此,您需要指定每个从根开始的包含路径。例如,博客->帖子->作者和博客->帖子->标签。这并不意味着您将获得多余的联接,在大多数情况下,EF会在生成SQL时合并联接。

You may want to include multiple related entities for one of the entities that is being included. For example, when querying Blogs, you include Posts and then want to include both the Author and Tags of the Posts. To do this, you need to specify each include path starting at the root. For example, Blog -> Posts -> Author and Blog -> Posts -> Tags. This does not mean you will get redundant joins, in most cases EF will consolidate the joins when generating SQL.

请注意最后一段。回顾一下,每个 Include / ThenInclude 链均表示要加载的实体 path 。包含路径中包含的每个实体仅包含一次。

Note the last paragraph. To recap, every Include / ThenInclude chain represents an entity path to be loaded. Each entity contained in the include paths is included just once.

这篇关于获取具有深层次相关实体的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆