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

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

问题描述

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

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 Object,另外我想得到我所有的相关对象从Transaction到TransactionDetailto (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)
                    ))
        );

我觉得我的代码不是那么干净整洁,因为对于 Transaction Detail 的每个相关实体,我实际上包含了多个 transaction detail 实例...我想做如下所示的操作,其中只包含一个 Transaction 实例详细但实体框架不允许我这样做:

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 链代表一个要加载的实体路径.包含路径中包含的每个实体仅包含一次.

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天全站免登陆