C# 获取具有深层相关实体的对象
假设我有一个一对一关系的实体类,如下所示:C# 获取具有深层相关实体的对象,c#,entity-framework-core,C#,Entity Framework Core,假设我有一个一对一关系的实体类,如下所示: 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 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获取所有相关对象
to(TransactionType/TransactionCategory/PaymentMethod/PaymentPayor),这是一个两级数据映射,我的函数类似于:
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)
))
);
公共异步任务GetSingleFullTransactionByIDAsync(int transactionID)
=>等待GetSingleOrDefaultAsync(
谓词:tr=>(tr.TransactionID==TransactionID),
包括:(obj=>(
obj
.Include(实体=>entity.TransactionDetailFk)
.然后包括(td=>td.paymentpayrfk)
.Include(实体=>entity.TransactionDetailFk)
.然后包括(td=>td.PaymentMethodFk)
.Include(实体=>entity.TransactionDetailFk)
.然后包括(td=>td.TransactionTypeFk)
.Include(实体=>entity.TransactionDetailFk)
.然后包括(td=>td.TransactionCategoryFk)
))
);
我觉得我的代码没有那么干净整洁,因为对于每个交易细节的相关实体,我实际上包括了多个交易细节实例……我想做如下的事情,只包括一个交易细节实例,但实体框架不允许我这样做:
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)
))
);
公共异步任务GetSingleFullTransactionByIDAsync(int transactionID)
=>等待GetSingleOrDefaultAsync(
谓词:tr=>(tr.TransactionID==TransactionID),
包括:(obj=>(
obj
.Include(实体=>entity.TransactionDetailFk)
.然后包括(td=>td.paymentpayrfk)
.然后包括(td=>td.PaymentMethodFk)
.然后包括(td=>td.TransactionTypeFk)
.然后包括(td=>td.TransactionCategoryFk)
))
);
那么,使用EF core的有效方法是什么呢?注意这里我使用的是存储库模式,所以我不能使用sql到linq表达式,而只需要使用“Include”/“thenclude”操作
我觉得我的代码不是那么干净整洁,因为对于每个事务细节的相关实体,我实际上包含了多个事务细节实例
这正是在EF Core中包含多个相关实体的预期(“设计”)方式。EF核心文件的章节中对其进行了解释(举例):
您可能希望为其中一个实体包含多个相关实体。例如,在查询博客时,您包括帖子,然后希望同时包括帖子的作者和标签。为此,需要指定从根开始的每个包含路径。例如,Blog->Posts->Author和Blog->Posts->Tags。这并不意味着您将获得冗余联接,在大多数情况下,EF将在生成SQL时合并联接
注意最后一段。总而言之,每个
Include
/然后Include
链表示要加载的实体路径。包含路径中包含的每个实体只包含一次。非常感谢您的解释和资源共享!