2017-12-18 398 views
0

對於下面的示例學生名單我想選擇使用表達式樹列表中多條記錄,選擇多個記錄(生成動態LINQ查詢)在C#中創建的表達式樹使用LINQ.Expressions

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

對於選擇單條記錄

SQL Query: 
select * from studentList where StudentID = 2 

LINQ:

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

我同樣需要創建的表達式樹從值

例如SQL查詢的列表中選擇多個記錄:

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

輸出樣本:

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

樣品表達樹代碼:

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; } 
} 

我可以創建一個用於選擇單個記錄的表達式代碼。但是我無法使用datalist中的多條記錄選擇值。請幫助我使用表達式條件選擇多個值。

回答

2

我認爲試圖用表達式來修復它是一個地獄般的工作。這些功能已經可以通過現有的方法實現。 (這使您的解決方案更簡單) ;-)

你可以試試這個:

// 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)); 

的ID陣列將被轉換爲IN (..)聲明。

1

可以爲此創建一個表達式樹,但這是做事困難的方式。更簡單的是剛剛創建的ID列表:

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

,只是使用:

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