Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 确定MemberExpressions目标的范围_C#_.net_Linq_Expression Trees_Custom Linq Providers - Fatal编程技术网

C# 确定MemberExpressions目标的范围

C# 确定MemberExpressions目标的范围,c#,.net,linq,expression-trees,custom-linq-providers,C#,.net,Linq,Expression Trees,Custom Linq Providers,这里有没有人有编写自定义Linq提供程序的经验 我要做的是告诉您,作为业务对象属性的MemberExpression是应该包含在SQL中,还是应该被视为常量,因为它来自恰好是业务对象的局部变量 例如,如果您有: Customer c = LoadCustomerFromDatabase(); var orders = from o in db.Orders() where o.CustomerID == c.CustomerID select o; 目前,我的查询翻译器将尝试从订单o执行SE

这里有没有人有编写自定义Linq提供程序的经验

我要做的是告诉您,作为业务对象属性的MemberExpression是应该包含在SQL中,还是应该被视为常量,因为它来自恰好是业务对象的局部变量

例如,如果您有:

Customer c = LoadCustomerFromDatabase();

var orders = from o in db.Orders() where o.CustomerID == c.CustomerID select o;
目前,我的查询翻译器将尝试从订单o执行
SELECT*,其中o.CustomerID=c.CustomerID
,这当然不起作用

我想做的是检查
c.CustomerID
上的MemberExpression,并尝试确定它是一个局部变量,还是只是用作Linq表达式的一部分


我已经设法把它作为查询的第二步,查找SQL Server无法绑定的字段,并注入它们的值,但如果可能的话,我希望所有这些都同时发生。我尝试查看表达式
Type
属性和
IsAutoClass
,但这只是一个猜测,因为它包含单词Auto。它不起作用:)

嗯,我不知道你是否可以把它简化为一个过程,但是你可以得到关于成员的信息,如果它与你声明为查询一部分的另一个变量(在本例中为“o”)一致,你就用它来生成你的查询

否则,您将假定它是一个常量,然后插入该值


不幸的是,由于在查询中可以在多个位置使用from语句(除了let语句),因此似乎不能一次完成,因为您需要事先了解所有查询变量。

好的,在进行一些快速统计分析(即手动比较各个属性)后,DeclaringType,当Lambda参数不在范围“fires”中时,ReflectedType和Namespace是无效的


因此,除非有人提出更好的答案,否则这可能就是我要说的全部。

在Where表达式中,您看到的是
表达式
——这意味着最外层的lambda应该有一个
参数表达式
,类型为
T

如果比较与行相关,则它将(作为祖先)具有此
参数表达式
;如果它是局部变量,则它将(作为祖先)具有
常量表达式
——但是,编译器将生成此常量表达式的类型,以处理表达式中使用的所有捕获变量

像这样:

using System;
using System.Linq.Expressions;
class Foo
{
    public string Name { get; set; }
    static void Main()
    {
        var exp = (LambdaExpression) GetExpression();
        WalkTree(0, exp.Body, exp.Parameters[0]);

    }
    static void WriteLine(int offset, string message)
    {
        Console.WriteLine(new string('>',offset) + message);
    }
    static void WalkTree(int offset, Expression current,
        ParameterExpression param)
    {
        WriteLine(offset, "Node: " + current.NodeType.ToString());
        switch (current.NodeType)
        {
            case ExpressionType.Constant:
                WriteLine(offset, "Constant (non-db)"
                    + current.Type.FullName);
                break;
            case ExpressionType.Parameter:
                if (!ReferenceEquals(param, current))
                {
                    throw new InvalidOperationException(
                        "Unexpected parameter: " + param.Name);
                }
                WriteLine(offset, "db row: " + param.Name);
                break;
            case ExpressionType.Equal:
                BinaryExpression be = (BinaryExpression)current;
                WriteLine(offset, "Left:");
                WalkTree(offset + 1, be.Left, param);
                WriteLine(offset, "Right:");
                WalkTree(offset + 1, be.Right, param);
                break;
            case ExpressionType.MemberAccess:
                MemberExpression me = (MemberExpression)current;
                WriteLine(offset, "Member: " + me.Member.Name);
                WalkTree(offset + 1, me.Expression, param);
                break;
            default:
                throw new NotSupportedException(
                    current.NodeType.ToString());
        }
    }

    static Expression<Func<Foo, bool>> GetExpression()
    {
        Foo foo = new Foo { Name = "abc" };

        return row => row.Name == foo.Name;
    }    
}
使用系统;
使用System.Linq.Expressions;
福班
{
公共字符串名称{get;set;}
静态void Main()
{
var exp=(LambdaExpression)GetExpression();
WalkTree(0,exp.Body,exp.Parameters[0]);
}
静态void WriteLine(整数偏移量,字符串消息)
{
Console.WriteLine(新字符串('>',偏移量)+消息);
}
静态void WalkTree(整数偏移,表达式当前,
参数expression param)
{
WriteLine(偏移量,“节点:+current.NodeType.ToString());
开关(当前.节点类型)
{
大小写表达式类型。常量:
写线(偏移量,“常数(非db)”
+当前.Type.FullName);
打破
大小写表达式类型。参数:
如果(!ReferenceEquals(参数,当前))
{
抛出新的InvalidOperationException(
“意外参数:”+参数名称);
}
写入线(偏移量,“数据库行:”+参数名称);
打破
大小写表达式类型。相等:
BinaryExpression be=(BinaryExpression)当前值;
写线(偏移量,左:);
WalkTree(偏移量+1,向左,参数);
写线(偏移量,右:);
WalkTree(偏移量+1,右侧,参数);
打破
case ExpressionType.MemberAccess:
MemberExpression me=(MemberExpression)当前值;
WriteLine(抵销,“成员:+me.Member.Name”);
WalkTree(偏移量+1,me.Expression,参数);
打破
违约:
抛出新的NotSupportedException(
current.NodeType.ToString());
}
}
静态表达式GetExpression()
{
Foo Foo=新Foo{Name=“abc”};
返回row=>row.Name==foo.Name;
}    
}