标签: linq-expressions

这个linq表达式创建有什么问题(使用contains)

我试图用contains运算符动态创建一个linq表达式.

在阅读了与此主题相关的几篇帖子后,我提出了以下代码,允许我执行"包含"评估:

internal static Expression<Func<TEntity, bool>> StringContains<TEntity>(string propertyName, string subString)
{
    MethodInfo contains = typeof(JsonLinqParser_Paser).GetMethod("Like");
    var param = Expression.Parameter(typeof(TEntity));
    var body = Expression.Call(contains, Expression.Property(param, propertyName), Expression.Constant(subString, typeof(string)));

    var lambda = Expression.Lambda<Func<TEntity, bool>>(body, param);

    return lambda;
}
public static bool Like(string a, string b)
{
    return a.Contains(b);
}
Run Code Online (Sandbox Code Playgroud)

这就是这样称呼的:

var expression = Expression.Lambda<Func<TEntity, bool>>(StringContains<TEntity>("FIPSCO_STR", _myStringValue), param);
Run Code Online (Sandbox Code Playgroud)

但是,在运行时,我收到如下错误:

类型'System.Func`2 [DAL.BestAvailableFIP,System.Boolean]'的表达式不能用于返回类型'System.Boolean'

其中"DAL.BestAvailableFIP"是"TEntity"类型.

我确信这与我对lambda表达式缺乏了解有关.谁能告诉我我做错了什么?

c# lambda linq-expressions

2
推荐指数
1
解决办法
1543
查看次数

Expression.Coalesce in Linq to Entities

是否可以在Linq to Entities中使用该Expression.Coalesce方法(http://msdn.microsoft.com/en-us/library/bb302730.aspx)?怎么样?任何可用的例子?

c# linq linq-expressions

2
推荐指数
1
解决办法
3292
查看次数

使用Enum作为/表达式?

是否可以使用带表达式的枚举来反映枚举值?考虑这个假设的例程:

public enum Fruit
{
  Apple,
  Pear
}

public void Foo(Fruit fruit)
{
  Foo<Fruit>(() => fruit);
}

public void Foo<T>(Expression<Func<T>> expression)
{
    //... example: work with Fruit.Pear and reflect on it
}
Run Code Online (Sandbox Code Playgroud)

Bar() 会给我关于枚举的信息,但我想使用实际值.

背景:我一直在添加一些辅助方法来返回类型的CustomAttribute信息,并想知道类似的例程是否可以用于枚举.

我完全知道你可以使用枚举类型来获取CustomAttributes.

更新:

我在MVC中使用类似的概念和辅助扩展:

public class HtmlHelper<TModel> : System.Web.Mvc.HtmlHelper<TModel>
{
    public void BeginLabelFor<TProperty>(Expression<Func<TModel, TProperty>> expression)
    {
        string name = ExpressionHelper.GetExpressionText(expression);
    }
}
Run Code Online (Sandbox Code Playgroud)

在此示例中,name将是模型的成员名称.我想用枚举做类似的事情,所以名字将是枚举'成员'.这甚至可能吗?

更新示例:

public enum Fruit
{
  [Description("I am a pear")]
  Pear
}

public void ARoutine(Fruit fruit)
{
  GetEnumDescription(() => fruit); …
Run Code Online (Sandbox Code Playgroud)

c# linq-expressions

2
推荐指数
1
解决办法
1265
查看次数

声明从TDelegate到Expression <TDelegate>的隐式转换在哪里?

实际上,有四个相关的问题:

1)为什么可以这样做?

Expression<Func<int, int>> incrementorExpression = (i => i + 1);
Run Code Online (Sandbox Code Playgroud)

但是不能这样做?

LambdaExpression decrementorExpression = (i => i - 1);
Run Code Online (Sandbox Code Playgroud)

在第二种情况下,编译器因此报告:"无法将lambda表达式转换为类型'System.Linq.Expressions.LambdaExpression',因为它不是委托类型"

2)如果是的铸造TDelegateExpression<TDelegate>申报?我想我记得过去见过它但现在似乎无法找到它.但我无法确定我是否看到了它.

3)当我这样做时:

Expression<Func<int, int>> incrementExpression = (i => ++i);
Run Code Online (Sandbox Code Playgroud)

编译器说:"表达式树可能不包含赋值运算符." 为什么会这样?

4)如果我能做到这一点:

Expression<Func<int, int>> incrementorExpression = (i => i + 1);
Run Code Online (Sandbox Code Playgroud)

那么,为什么我不能做这个

public Expression<Func<T>> ToExpression<T>(Func<T> func)
{
  return func;
}
Run Code Online (Sandbox Code Playgroud)

.net c# linq lambda linq-expressions

2
推荐指数
1
解决办法
353
查看次数

Expression.ToString() 工作吗?

我有一个生成的 lambda,但是当我想观看它时,它就像一个普通的 lambda,它只是不显示任何内容。当我打电话时,expr.Body.ToString()我得到以下信息:

{var compareA; ... }
Run Code Online (Sandbox Code Playgroud)

但是用于表达式的 DebugView 工作正常:

.Lambda #Lambda1<System.Comparison`1[XLinq.Test.Comparers.CustomComparerTest+Test]>(
    XLinq.Test.Comparers.CustomComparerTest+Test $x,
    XLinq.Test.Comparers.CustomComparerTest+Test $y) {
    .Block(System.Int32 $compareA) {
        $compareA = .Call ($x.A).CompareTo($y.A);
        .If ($compareA != 0) {
            .Return #Label1 { $compareA }
        } .Else {
            .Block(System.Int32 $compareB) {
                $compareB = .Call ($x.B).CompareTo($y.B);
                .If ($compareB != 0) {
                    .Return #Label1 { $compareB }
                } .Else {
                    .Block(System.Int32 $compareC) {
                        $compareC = .Call ($x.C).CompareTo($y.C);
                        .If ($compareC != 0) {
                            .Return #Label1 { $compareC }
                        } .Else {
                            .Block(System.Int32 …
Run Code Online (Sandbox Code Playgroud)

.net c# lambda linq-expressions

2
推荐指数
1
解决办法
1813
查看次数

o?.Value的表达式树

我想用Expression树生成这个句子:

o?.Value
Run Code Online (Sandbox Code Playgroud)

o 是任何一个类的实例.

有什么办法吗?

c# linq linq-expressions null-propagation-operator

2
推荐指数
1
解决办法
329
查看次数

按键表达存储静态过滤器

我有一个函数生成一个表达式来过滤一个表的主键,当传入时Object[],这与Find函数非常相似,只是它没有实现,所以你可以IQueryable在之后传递一个

public static Expression<Func<T, bool>> FilterByPrimaryKeyPredicate<T>(this DbContext dbContext, object[] id)
{
    var keyProperties = dbContext.GetPrimaryKeyProperties<T>();
    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<T, bool>>(body, parameter);
}
Run Code Online (Sandbox Code Playgroud)

这通过首先获取表的主键,它创建二进制表达式foreach属性,Id以匿名类型包装以利用查询缓存.这工作正常.但是,我想更进一步.

我想保留Expression,所以每次传递一组新的id时我都不必生成它,如何Expression在仍然利用查询缓存的同时存储它?

编辑TL; DR

所以我试图在静态类中使用数组访问来缓存它,但是我遇到了一个错误:

public class PrimaryKeyFilterContainer<T>
{
    const string ANON_ID_PROP = "id";
    static Expression<Func<T, bool>> _filter; …
Run Code Online (Sandbox Code Playgroud)

c# entity-framework query-cache linq-expressions .net-core

2
推荐指数
1
解决办法
76
查看次数

演员表达

我有以下内容:

class Base
class Derived : Base
IQueryable<Derived> queryable = ???
Expression<Func<Base, bool>> filter = ???
Run Code Online (Sandbox Code Playgroud)

我想用表达式过滤可查询,然后返回一个IQueryable<Derived>.

但是,Expression是不变的.这意味着queryable.Where(filter)被推断为Where(this IQueryable<Base>, Expression<Func<Base, bool>>),IQueryable<Base>而不是返回IQueryable<Derived>.

C#不允许filter被转换为Expression<Func<Derived, bool>>和的铸造IQueryable<Base>返回通过WhereIQueryable<Derived>在运行时出现故障.

围绕这个最好的方法是什么?

c# iqueryable variance linq-expressions

2
推荐指数
1
解决办法
172
查看次数

在编译时获取非静态方法的 MethodInfo

我正在开发一个程序,该程序根据一组输入在运行时计算表达式,然后远程执行这些表达式。这需要动态创建调用不同辅助函数的表达式。

对于静态辅助函数,可以通过使用以下方式获取 MethodInfo 实例来保证编译时安全:

var myMethodInfo = ((Func<int, int>) Helpers.MyStaticHelper.DoSomethingUseful).Method
Run Code Online (Sandbox Code Playgroud)

使用这个,如果Helpers.MyStaticHelper.DoSomethingUseful要更改它的名称或签名,这将导致编译时错误。但是,它似乎仅适用于静态方法。对非静态使用类似的方法给出了 CS0120An object reference is required for the nonstatic field, method, or property 'Helpers.MyDynamicHelper.DoSomethingElse(int, int)'

可以通过使用类似以下内容来解决此问题:

var myMethodInfo = typeof(Helpers.MyDynamicHelper).GetMethod("DoSomethingElse")
Run Code Online (Sandbox Code Playgroud)

DoSomethingElse但是,如果更改,这将面临运行时异常的风险。我知道在没有实例的情况下不可能调用该方法,但是收集和缓存先决数据需要这些实例,因此在执行表达式之前创建的任何实例都是不正确的。

是否可以在没有实例的情况下获得该方​​法的编译时安全 MethodInfo?

c# linq reflection linq-expressions

2
推荐指数
1
解决办法
151
查看次数

C#表达式 - 从另一个表达式创建表达式

我试图使用看起来像这样的表达式创建一个可重用的方法:

Expression<Func<Order, bool>> CreateExpression(Expression<Func<Order, int>> parameter, FilterOperator operator, int value)
Run Code Online (Sandbox Code Playgroud)

所以我可以像这样使用它:

IQueryable<Order> orders = db.Orders;

var filtered = orders.Where(CreateExpression(o => o.OrderID, FilterOperator.GreaterThan, 100));
Run Code Online (Sandbox Code Playgroud)

我不知道怎么写这个方法.如何编写一个为我创建此Expression的方法?

我需要能够做这样的事情:

if(operator == FilterOperator.GreaterThan)
   return m => m.OrderID > value;
else if(operator == FilterOperator.LessThan)
   return m => m.OrderID < value;
Run Code Online (Sandbox Code Playgroud)

但我想使用传入的表达式而不是直接使用OrderID.我怎样才能做到这一点?

c# linq-expressions

1
推荐指数
1
解决办法
133
查看次数