首页 > 解决方案 > 动态 EF Linq 使用反射、成员表达式或任何东西加入导航属性

问题描述

我正在尝试为实体框架创建一个全局查询过滤器(https://docs.microsoft.com/en-us/ef/core/querying/filters

我想在我的 dbcontext 中的每个实体上应用自定义左连接。现在,表连接(https://www.tutorialsteacher.com/linq/linq-joining-operator-join)带来了困难,因为内部/外部序列的键选择器似乎必须是相同的类型(整数,字符串等)。

但是,如果我对我的加入进行硬编码,如下所示:

standardList,  // inner sequence 
student => student.StandardID,    // outerKeySelector
standard => standard.StandardID,  // innerKeySelector
(student, standard) => new  // result selector
{
StudentName = student.StudentName,
StandardName = standard.StandardName
});

我们没有问题,因为键选择器都是相同类型(int)的导航属性。伟大的!然而,

对于我的应用程序,我将以下内容插入到字典中:实体、导航属性(例如:Student.Parent.Id)。这作为类型存储在我的字典中: Expression<Func<TEntity, TProperty>> 对于我注册的每个实体,如下所示:

Class().Register<Person, int>(x => x.Parent.Id)

然后我希望能够使用以下方法循环所有实体:Using Global Query Filters for allentities

然而,在我的实现中出现的困难是,当我们遍历它们时,我无法找到一种方法来换入和换出键选择器,因为它们被存储为不同的实体类型,这意味着当我尝试引用它无法加入的表达式时因为它们有两种不同的类型,即实体,实体。(即使这两个属性都是相同的类型(int)。我希望成员表达式可能会有所帮助,但我对它们没有运气,也没有运气创建一个拉姆达表达式。

我已经尝试过示例(sudo):

var x = Expression.Parameter(typeof(Person), "x");
var body = Expression.PropertyOrField(x, "Id");
var lambda = Expression.Lambda<Func<Person,int>>(body, x);

Expression<Func<TEntity, bool>> test = x => dbset<Person>.Join( dbset<Parent>, 
b => lambda , c => lambda 
(b, cda) => new {b, cda})
.Where(y => y.Person.Id == 1).Any()
)

var testb = typeof(TEntity).GetProperty("Id");

//I know this would join to itself but would at least join for a test. Compiles but the query cant' be translated exception probably because it says the outer and inner joins are: (object)(int)(PropertyInfo)Int32 Id.GetValue() which I dont think translate like it says
Expression<Func<TEntity, bool>> test = x => dbset<Person>.Join( dbset<Parent>, 
b => (int)testb.GetValue(b, null) , c => (int)testb.GetValue(c, null)
(b, cda) => new {b, cda})
.Where(y => y.Person.Id == 1).Any()
)



这非常令人沮丧,因为我认为这实现起来并不那么复杂,而且我花了几天时间试图实现一些在纸上听起来很简单的东西,只需用我之前创建的一个硬编码表达式替换一个硬编码表达式!

我研究了表达式、成员表达式、lambda 编译、反射、委托,但 Google 上的所有内容现在都是紫色的。任何人都可以在这里给我一些指导吗?

必须可以基于存储的导航属性在所有实体上应用上述连接

标签: c#asp.netentity-framework.net-coredelegates

解决方案


推荐阅读