我使用带有反射的实体框架核心来动态生成一些表单。除了where子句外,一切正常。我得到以下错误:
表达式树不能包含动态操作
我可以通过将iqueryable转换为一个列表来解决这个问题,但这会引入我希望避免的不同问题。
这是我的密码:
public async void ViewCollection(PropertyInfo propertyInfo)
{
Type propertyType = propertyInfo.PropertyType;
InversePropertyAttribute inversePropertyAttribute = (InversePropertyAttribute)ReflectionHelpers.GetAttribute(propertyInfo, typeof(InversePropertyAttribute));
//GET THE TYPE OF THE COLLECTION
Type collectionType = propertyInfo.PropertyType.GenericTypeArguments[0];
//GET THE INVERSE PROPERTY INFO
PropertyInfo inverseProperty = collectionType.GetProperty(inversePropertyAttribute.Property);
//GET THE FOREIGN KEY ATTRIBUTE FROM THE INVERSE PROPERTY
ForeignKeyAttribute foreignKeyAttribute = (ForeignKeyAttribute)ReflectionHelpers.GetAttribute(inverseProperty, typeof(ForeignKeyAttribute));
//GET THE FOREIGN KEY PROPERTY FROM THE FOREIGN KEY ATTRIBUTE
PropertyInfo foreignKeyProperty = collectionType.GetProperty(foreignKeyAttribute.Name);
//GET INCLUDED TYPE NAMES BY FOREIGN KEY
IEnumerable<string> includedTypes = collectionType.GetProperties().Where(p => p.PropertyType.IsClass).Where(p => ReflectionHelpers.HasAttribute(p, typeof(ForeignKeyAttribute))).Select(r => r.Name);
//GET THE DATA SET
IQueryable<dynamic> items = ReflectionHelpers.GetDbCollectionByType(Db, collectionType);
//INCLUDE THE INCLUDED TYPES BY NAME
foreach (string includedType in includedTypes) items = items.Include(includedType);
//THIS IS WHERE THE ERROR IS
items = items.Where(i => foreignKeyProperty.GetValue(i, null) == PrimaryKeyProperty.GetValue(Item, null));
await ShowCollection(collectionType, items, propertyInfo.Name);
}
我怎样才能解决这个问题而不改变我的类型列表?
2条答案
按热度按时间y1aodyip1#
你不能。iqueryable是语言集成查询(linq)的一部分—它是静态类型的,因此不能使用值类型。
iqueryable幕后是一个表达式树,它表示尚未执行的查询。表达式树部分表示查询。静态类型表示查询对其进行操作的数据。
最好的选择是使用expressiontreeapi手工构建表达式树。
c90pui9n2#
不能在上面生成查询
dynamic
因为它在表达式树中本机不受支持。相反,你应该把你的工作建立在非泛型的基础上IQueryable
或通用IQueryable<object>
. e、 g.如果ReflectionHelpers.GetDbCollectionByType
正在呼叫DbContext.Set<T>
动态地(类似于这里的efcore2.0中的动态访问表),您应该能够将它强制转换为IQueryable<object>
:添加
Where
子句中,不应在 predicate 表达式内使用反射调用,而应使用Expression
类方法(从System.Linq.Expressions
命名空间)。像这样:然后