Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# 从包含参数的成员表达式中提取值_C#_Linq_Expression_Mdx_Expression Trees - Fatal编程技术网

C# 从包含参数的成员表达式中提取值

C# 从包含参数的成员表达式中提取值,c#,linq,expression,mdx,expression-trees,C#,Linq,Expression,Mdx,Expression Trees,如果成员表达式中的表达式不是常量,而是参数表达式,如何从成员表达式中提取值 我正在为我们公司构建一个小型Linq到MDX ORM 在我的生成器模板中,在数据库中找到的每个维度都是一个类,在每个维度中,都有该维度的属性属性。生成所有维度类后,将生成一个更高级别的Cube类,其中包含作为属性的维度以及该多维数据集的度量值。生成所有多维数据集类后,将生成最后一个类,其中包含作为cube属性生成的多维数据集类,其中cube是我的IQueryable类型。这里有一个例子 //Generated cs fi

如果成员表达式中的表达式不是常量,而是参数表达式,如何从成员表达式中提取值

我正在为我们公司构建一个小型Linq到MDX ORM

在我的生成器模板中,在数据库中找到的每个维度都是一个类,在每个维度中,都有该维度的
属性
属性。生成所有维度类后,将生成一个更高级别的
Cube
类,其中包含作为属性的维度以及该多维数据集的度量值。生成所有多维数据集类后,将生成最后一个类,其中包含作为
cube
属性生成的多维数据集类,其中
cube
是我的
IQueryable
类型。这里有一个例子

//Generated cs file example:
public partial MyDatabase : CubeBase
{
    //Some base implementation goes here        

    public Cube<FooCube> FooCube { get { return new Cube<FirstCube>(new Provider("connection string"); } }

    //Any other cubes would follow here that were found on this database.
} 

//A calendar dimension
public class FooCube_CalendarDimension
{
    public Attribute WeekEnding { get { return new Attribute("[Calendar].[Week Ending]"); } }

    public Attribute Month { get { return new Attribute("[Calendar].[Month]"); } }

    public Attribute Year { get { return new Attribute("[Calendar].[Year]"); } }
}

//The "FooCube" 
public partial class FooCube
{
    //List Dimensions
    public FooCube_Calendar_Dimension Calendar { get { return new FooCube_Calendar_Dimension(); }     }
    //Other dimensions here

    [Measure]
    public string RetailDollars { get { return "[Retail Dollars]"; } }
    // Other measures here
}
例如,我试图从cube.Calendar.Month.Children获取值,该值来自属性对象,该属性对象是FooCube\u Calendar\u Demsion类的一个属性,它本身就是“FooCube”类中的一个属性


我尝试了来自的答案,但在尝试编译lambda表达式时出现了错误“未引用'cube'参数”。它传递给属性类的构造函数的值存储在属性中,这就是我想要访问的值(其中一个)。

基本上,您不能。至少,这是不明智的。目前,您所拥有的只是一个查询。实际上,您没有对象的集合,您只知道创建这些对象需要执行哪些操作。您当前正在编写的查询提供程序的任务是实际构建查询定义的对象并返回它们

您已经设计了您的程序,以便创建对象的查询提供程序需要已经创建了对象,以便正确构建查询。不可能已经由您尚未构建的查询定义了对象。您已经为自己创建了一个循环依赖项


对于您来说,重要的是提供构建查询所需的信息,而不是在查询本身创建的对象实例中。通常,这是通过属性上的属性来完成的,或者通过基于关于类型本身的其他现有C#元数据的查询来完成的。此类型数据存在,并且您的查询提供程序可以访问,而不需要您负责创建的对象的任何实际实例。

我之所以添加此答案,是因为我找到了两种提取所需值的方法。不过,我要感谢Servey的回答,因为他确实是正确的,没有以任何合理的方式进行操作,因为我已经编写了代码

我发现有两种方法可以解决这个问题

  • 使用带有泛型参数的泛型转换器类,该泛型参数是lambda表达式所需参数的类类型,然后将该泛型参数用作
    Func delgate
    上的输入参数。这是最好、最快的方法,因为在运行时没有动态操作
  • var lambda=Expression.lambda(//此处的表达式)

  • 我发现的第二种方法比较慢,因为它涉及到
    Delegate.DynamicInvoke()
    方法,但确实有效

    var lambda=Expression.lambda(member,(ParameterExpression)member.Expression);
    var d=lambda.Compile();
    返回d.DynamicInvoke(member.Expression.Type.GetConstructors()[0].Invoke(新对象[0])


  • 这将获得对象的值,但由于动态调用,成本很高

    具体来说,您试图从该查询中获取什么值?该查询中有许多成员表达式;你需要弄清楚你要评估的是哪一个。属性类中有一个“Tag”属性。这就是“[Calendar].[Month]”字符串的存储位置。还有一个“Children”属性,它将“.Children”连接到值并返回“[Calendar].[Month].CHILDREN。这些是我想要的值。您应该使用属性的C#attributes来获取有关创建查询时使用的属性的信息。从属性返回的值应该是查询的结果,而不是创建查询时使用的值。当您的属性对其使用C#attributes时,您可以检查这些属性e值,而不需要这些类型的特定实例。这里以EF为例。这就是我采用的方法,例如[Tag(Tag=“[Calendar].[Month]”),这很好,但我还想让用户能够在另一个分部类中添加查询范围内的用户成员和集,以便他们可以在linq查询中调用这些成员和集,我希望他们能够使用生成的对象这样做。此外,我希望用户能够使用“let”动态添加这些计算成员“linq查询中的表达式。唯一能够做到这一点的方法是从这些挑剔的成员表达式中提取值。这是有意义的。我对表达式和linq查询仍然很陌生,但我理解你的意思。如果没有整个用户创建的成员和集合,我将是金色的。也许我将不得不以不同的方式实现这些。
    //using MyDatabase = db
    var mdx = from cube in db.FooCube
              where cube.Calendar.Year == "2014"
              select new
              {
                  Month = cube.Calendar.Month.Children
                  Dollars = cube.RetailDollars
              }