简体   繁体   English

在C#中创建表达式树以使用LINQ.Expressions选择多个记录

[英]create Expression tree in c# to select multiple records using LINQ.Expressions

For the following sample student list I want to select multiple records from the list using Expression tree(to generate dynamic LINQ query) 对于以下示例学生列表,我想使用表达式树从列表中选择多个记录(以生成动态LINQ查询)

 - 1 | John  | 13
 - 2 | Steve | 15
 - 3 | Bill  | 18
 - 4 | Ram   | 12
 - 5 | Ron   | 21

For selecting single record 用于选择单个记录

SQL Query:   
select * from studentList where StudentID = 2  

LINQ: LINQ:

var studentsData = studentList.Where(s=>s.StudentID == 2).AsQueryable();

likewise I need to create Expression tree for selecting multiple records from the list of values 同样,我需要创建表达式树以从值列表中选择多个记录

For example SQL Query: 例如SQL查询:

From the list of IDs I need create expression for selecting records     
select * from studentList where StudentID in (2,4,3) 

sample Output: 样本输出:

 - 2 | Steve
 - 4 | Ram
 - 3 | Bill  

Sample Expression tree Code: 样本表达树代码:

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Collections.Generic;

public class Program
{
public static void Main()
{
    IList<Student> studentList = new List<Student>() { 
        new Student() { StudentID = 1, StudentName = "John", Age = 13 } ,
        new Student() { StudentID = 2, StudentName = "Steve",  Age = 15 } ,
        new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
        new Student() { StudentID = 4, StudentName = "Ram" , Age = 12 } ,
        new Student() { StudentID = 5, StudentName = "Ron" , Age = 21 } 
    };
    var studentwithLinQ = studentList.Where(s=>s.StudentID == 2);
    foreach(var stu in studentwithLinQ)
    Console.WriteLine("{0} | {1}",stu.StudentID, stu.StudentName);
    ParameterExpression pe = Expression.Parameter(typeof(Student), "s");
    MemberExpression me = Expression.Property(pe, "StudentID");
    int id = 2;
    ConstantExpression constant = Expression.Constant(id, typeof(int));
    BinaryExpression body = Expression.Equal(me, constant);
    Expression predicateExpression = Expression.Lambda(body, pe);
    var sourcequery = studentList.AsQueryable();
    Expression sourceExpression = Expression.Convert(Expression.Constant(sourcequery), typeof(IQueryable<Student>));
    Expression filterExpressionExpression = Expression.Constant(predicateExpression);
    var queryExpression = Expression.Call(typeof(Queryable), "Where", new Type[] { typeof(Student)}, sourceExpression,filterExpressionExpression);
    sourcequery = Expression.Lambda(queryExpression).Compile().DynamicInvoke() as IQueryable<Student>;
    Console.WriteLine("sourceExpression: {0}", sourcequery);
    var studentWithExpression = sourcequery;
    foreach(var stu in studentWithExpression)
    Console.WriteLine("{0} | {1}",stu.StudentID, stu.StudentName);
   }
 }

public class Student{
   public int StudentID { get; set; }
   public string StudentName { get; set; }
   public int Age { get; set; }
}

I can create a Expression code for selecting single record. 我可以创建用于选择单个记录的表达式代码。 But i am not able to select the values using multiple records from datalist.can you please help me to select multiple values using Expression Statments. 但是我无法使用数据列表中的多个记录来选择值。请您帮我使用表达状态来选择多个值。

I think trying to get it fixed with expressions it a hell of a job. 我认为尝试用表达式解决问题是一件很艰辛的事情。 These functionality can already be achieved with existing methods. 这些功能已经可以通过现有方法实现。 (which keeps your solution much more simplistic) ;-) (这使您的解决方案更加简单) ;-)

You could try this: 您可以尝试以下方法:

// your original set
IList<Student> studentList = new List<Student>() { 
    new Student() { StudentID = 1, StudentName = "John", Age = 13 } ,
    new Student() { StudentID = 2, StudentName = "Steve",  Age = 15 } ,
    new Student() { StudentID = 3, StudentName = "Bill",  Age = 18 } ,
    new Student() { StudentID = 4, StudentName = "Ram" , Age = 12 } ,
    new Student() { StudentID = 5, StudentName = "Ron" , Age = 21 } 
};

// create a subselection of ids only into an array(or list) of the id's only.
// results in `int[] { 1, 2, 3, 4, 5 };`
var ids = studentList.Select(student => student.StudentID).ToArray();

// use it on the studentList.
var studentwithLinQ = studentList.Where(s => ids.Contains(s.StudentID));

The ids array will be converted to an IN (..) statement. ids数组将转换为IN (..)语句。

You can create an expression tree for this, but that is doing things the hard way. 可以为此创建一个表达式树,但是这样做很困难。 Much simpler is to just create a list of the ids: 更简单的是只创建一个ID列表:

var ids = new List<int> { 2, 3, 4 };

and just use: 并使用:

var filtered = studentList.Where(x => ids.Contains(x.StudentID));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM