Tag: linq expressions

ValueTypes的动态表达式生成问题

我构建了一个框架,允许对表中的报表数据进行级联排序,具体取决于哪个列是主排序列。 它在很大程度上起作用,除了一个特定但重要的情况:当字段的属性是值类型时。 我收到以下错误消息: System.ArgumentException:类型’System.Int32’的表达式不能用于返回类型’System.Object’ 我知道这意味着我需要设置ValueType的值,但我不完全确定如何在这种特殊情况下。 根据一些研究和这个SO答案,我认为我需要以某种方式使用Expression.Convert 。 我的代码是生成表达式的代码。 generics类型参数T是数据“行”的类型。 GetFullSortOrder()只返回一个字符串数组,这些字符串表示类型T中也将进行排序的列(属性)的名称。 public IEnumerable<Expression<Func>> GetExpressions(string sortedColumn) where T : IReportRecord { var columns = GetFullSortOrder(sortedColumn) var typeParameter = Expression.Parameter(typeof(T)); foreach (var c in columns) { var propParameter = Expression.Property(typeParameter, c); yield return Expression.Lambda<Func>(propParameter, typeParameter); } } 当在T中选择的属性是ValueType时处理Expression.Lambda<Func>()时抛出exception。 属性框需要什么,或者在运行时才知道类型时返回正确的值?

LINQ:使用AND序列构建动态filter

我正在努力动态创建这样的查询: Dictionary parms = new Dictionary(); foreach (var kvp in parms) { var exp = ReportDefinitions.Where(x=> x.Discriminants.Any(y=> y.Key == kvp.Key && y.Value == kvp.Value) // && more conditions to add here at each cycle ); } ReportDefinitions.Discriminants是IDictionary ; 我知道如何构建简单的Expression但我无法弄清楚如何构建这个“Any”似乎真的很复杂。 Any称之为很难解决 谁知道如何处理这个?

类型’System.Int32’的表达式不能用于方法’Boolean Equals(System.Object)’的’System.Object’类型的参数

我有一个常见的网格视图列筛选器方法,使用ColumnName和SearchText明智地筛选网格视图记录。 这里当我在nullable int datacolumn上运行时,从这个方法抛出错误,如: 类型’System.Int32’的表达式不能用于方法’Boolean Equals(System.Object)’的’System.Object’类型的参数 我的方法代码是: public static IQueryable FilterForColumn(this IQueryable queryable, string colName, string searchText) { if (colName != null && searchText != null) { var parameter = Expression.Parameter(typeof(T), “m”); var propertyExpression = Expression.Property(parameter, colName); System.Linq.Expressions.ConstantExpression searchExpression = null; System.Reflection.MethodInfo containsMethod = null; // this must be of type Expression to accept different […]

动态添加新的lambda表达式以创建filter

我需要对ObjectSet进行一些过滤,以通过这样做获取我需要的实体: query = this.ObjectSet.Where(x => x.TypeId == 3); // this is just an example; 稍后在代码中(以及在启动延迟执行之前)我再次过滤查询,如下所示: query = query.Where(); 到目前为止,这非常有效。 这是我的问题: 实体包含DateFrom属性和DateTo属性,它们都是DataTime类型。 它们代表了一段时间 。 我需要过滤实体,只获得那些属于时间段 集合的实体。 集合中的句点不一定是连续的 ,因此,检索实体的逻辑看起来像: entities.Where(x => x.DateFrom >= Period1.DateFrom and x.DateTo x.DateFrom >= Period2.DateFrom and x.DateTo <= Period2.DateTo) || ……以及集合中所有时期的不断变化。 我试过这样做: foreach (var ratePeriod in ratePeriods) { var period = ratePeriod; query […]

智能表达翻译

我正在创建一个IQueryable,我想用它来传递给entity framework的查询。 我的存储库不公开可查询。 var query = new List().AsQueryable().Where(x => x.Property == “argument”); 我的存储库中有一个方法可以接收IQueryable。 如何使用相同的可查询来查询我的DbSet? 我试图从可查询中提取表达式为dbset构建一个新的表达式。 这是我到目前为止,但它不起作用: public IDbSet DbSet { get; set; } public IEnumerable Find(IQueryable queryable) { var parameter = Expression.Parameter(typeof (TEntity)); var body = queryable.Expression; var lambda = Expression.Lambda<Func>(body, parameter); var result = DbSet.Where(lambda); return null; } 当我尝试使用以下错误创建lambda时代码失败:类型’System.Linq.IQueryable`1 [MyTEntity]’的表达式不能用于返回类型’System.Boolean’ 我显然没有正确构建表达式,我缺少什么? 有没有更简单的方法来做我想要完成的事情? 我还看到一些示例表明Expression应该有一个参数属性。 但无论我转换为什么类型的表达式类型,并且这个是ConstantExpression,我都没有看到IQueryable.Expression中的参数属性。

如何在lambda表达式中设置断点?

我想调试在表达式树中调用的lambda。 不幸的是,断点永远不会被击中。 这是一个完整的控制台程序: private static void Main() { var evalAndWrite = EvalAndWrite(x => x + 1 /* a breakpoint here is never hit */); evalAndWrite(1); Console.ReadLine(); } private static Action EvalAndWrite(Expression<Func> expr) { var result = Expression.Variable(typeof(int), “result”); var assign = Expression.Assign(result, expr.Body); var writeLine = Expression.Call(typeof(Console), nameof(Console.WriteLine), null, result); var body = Expression.Block(new[] {result}, […]

按键表达存储静态filter

我有一个函数生成一个表达式来过滤一个表的主键,当它在Object[]传递时,这与Find函数非常相似,只是它没有实现,所以你可以在之后传递一个IQueryable public static Expression<Func> FilterByPrimaryKeyPredicate(this DbContext dbContext, object[] id) { var keyProperties = dbContext.GetPrimaryKeyProperties(); var parameter = Expression.Parameter(typeof(T), “e”); var body = keyProperties // e => e.{propertyName} == new {id = id[i]}.id .Select((p, i) => Expression.Equal( Expression.Property(parameter, p.Name), Expression.Convert( Expression.PropertyOrField(Expression.Constant(new { id = id[i] }), “id”), p.ClrType))) .Aggregate(Expression.AndAlso); return Expression.Lambda<Func>(body, parameter); } 这首先获取表的主键,它创建二进制表达式foreach属性,Id以匿名类型包装以利用查询缓存。 这工作正常。 但是,我想更进一步。 […]

成员表达式无法从可空小数转换为对象

我正在研究MVC项目,并希望将Html.TextboxFor方法传递给属性的名称。 这是我的viewmodel public class RuleViewModel where T : class, IValidatableObject { private T _rule; public T RuleModel { get { return _rule ?? (_rule = Activator.CreateInstance()); } } public RuleMetadata Metadata { get; set; } public Expression<Func<RuleViewModel, Object>> GetParameterByName(PropertyInfo pi) { var fieldName = Expression.Parameter(typeof(RuleViewModel), “x”); var fieldExpression = Expression.PropertyOrField(Expression.Property(fieldName, “RuleModel”), pi.Name); var exp = […]

具有嵌套属性的动态linq表达式树

我有一个列表,我必须过滤子属性。 filter运算符是动态的,我正在使用谓词构建器来组合多个filter/ lambdas。 为简单起见,假设我有两个这样的类: public class FirstClass { public int Id { get; set; } public ICollection MyList { get; set; } } public class SecondClass { public int ReferenceId { get; set; } public int Value { get; set; } } 我的filter使用引用ID,运算符类型和值,这样伪代码就像这样: “list of FirstClass”.Where(param1 => param1.MyList.Single(param2 => param2.ReferenceId == “reference id”).Value “operatorType” “value”) […]

组合多个表达式以动态创建包含表达式的select表达式作为getter

给出两个表达式的输入,例如: Expression<Func> nameExpression = x=>x.Name; Expression<Func> nameExpression = x=>x.MarketSegment.Name; 和a IQueryable query = ..//fetch from dbContext; 我想动态创建一个表达式,从查询中选择这些属性。 最终结果必须执行如下: Expression<IQueryable,IQueryable> query = query.Select(x=>new{ x=>x.Name, x=>x.MarketSegment.Name }); 我发现Expression.New可能是这个问题的一个选项,但我无法弄清楚如何将表达式传递给它。