如何获得实体框架查询中涉及的实体类型?

本文关键字:实体 类型 何获得 框架 查询 | 更新日期: 2023-09-27 18:12:00

如果我有一个EF查询:

var model = testContext.PurchaseOrders
               .Include(order => order.CompanyAccountingCodeNumber)
               .Include(order => order.CompanyAccountingCodeNumber.AccountingCode);

是否有办法找出特定查询中涉及的EF实体的类型。例如:

Test.Models.PurchaseOrder
Test.Models.CompanyAccountingCodeNumber
Test.Models.AccountingCode

所以我希望能够获得类型的IEnumerable,以便我可以获得名称空间等?

我假设这样的事情是可能的- Automapper支持Project().To<>,它可以找出需要哪些包含。所以我想使用include属性的反射会给我它们的类型

如何获得实体框架查询中涉及的实体类型?

我没有时间为此产生工作代码,但是每个IQueryable都有一个Expression属性,该属性包含一个表达式树,该表达式树表示对该IQueryable进行的各种链式调用。从理论上讲,您可以深入研究该表达式树,并对其中的表达式进行反思,以尝试确定"触及"的内容。

为了获得最大的收益,我建议扩展ExpressionVisitor类,使您能够轻松地深入遍历表达式树,并为您认为可能为您提供感兴趣的信息(如成员访问表达式)的表达式类型重写特定的方法。在这些被覆盖的方法中,在私有字段中捕获您需要的信息,然后在return base.[SameMethod](expr);中捕获。

尽管这是可能的,但我怀疑这是否真的是个好主意。根据我的经验,最好让一个类负责缓存特定类型的DTO,并在该类中放置两个事件侦听器,它们负责在数据中进行某些类型的更改时使特定的缓存条目无效。

如何在存储库中实现这些LINQ查询,然后在最后的方法调用中将涉及的实体类型存储在某些存储库属性中?

public interface IWithInvolvedDomainObjects 
{
     IEnumerable<Type> LatestInvolvedDomainObjectTypes { get; }
}
public interface IPurchaseRepository : IWithInvolvedDomainObjects 
{
     IEnumerable<PurchaseOrder> GetPurchaseOrders();
}
public class PurchaseRepository : IPurchaseRepository
{
      public IEnumerable<Type> LatestInvolvedDomainObjectTypes { get; private set; }
      public IEnumerable<PurchaseOrder> GetPurchaseOrders()
      {
           LatestInvolvedDomainObjectTypes = new[]
           {
                typeof(PurchaseOrder)
           };
           return testContext.PurchaseOrders
               .Include(order => order.CompanyAccountingCodeNumber)
               .Include(order => order.CompanyAccountingCodeNumber.AccountingCode);
      }
}