2009-04-10 33 views
7

Xin chào Tôi đang tìm phương pháp tốt nhất để viết truy vấn LINQ động.Cách tốt nhất để tạo truy vấn LINQ động

Tôi có một chức năng như

public IQueryable<Student> FindByAllStudents(int? id, string Name, int? CourseID, bool? IsActive) // like this way, all field values are passed 
    {  
     // code for compairision 
     return db.Student; 
    } 

chúng ta cũng có thể viết db.Students.where (predicate)

hoặc

một truy vấn như

var students = from s in db.students where s.Name.Contains(Name) 
       s.ID.Equals(id) 
       //and so on.... 

Vì vậy, sẽ này phương pháp hoạt động nếu tôi không vượt qua ID (tức là Null)? là cách thích hợp cho tất cả các kiểu dữ liệu?

Điểm là hàm có thể có tất cả các giá trị null làm tham số cho sự tương đương của lựa chọn * từ câu lệnh.

bất kỳ ai có thể giúp tôi xây dựng truy vấn tốt nhất bằng mã mẫu không?

Trả lời

20

Được rồi, nó không hoàn toàn rõ ràng những gì bạn muốn, nhưng nếu bạn đang cố gắng chỉ làm tăng thêm nơi khoản cho các thông số đó đều là phòng không null, bạn có thể làm:

public IQueryable<Student> FindByAllStudents 
    (int? id, string name, int? courseID, bool? isActive) 
{  
    IQueryable<Student> query = db.Student; 
    if (id != null) 
    { 
     query = query.Where(student => student.ID == id.Value); 
    } 
    if (name != null) 
    { 
     query = query.Where(student => student.Name.Contains(name)); 
    } 
    if (courseID != null) 
    { 
     query = query.Where(student => student.CourseID == courseID.Value); 
    } 
    if (isActive != null) 
    { 
     query = query.Where(student => student.IsActive == isActive.Value); 
    } 
    return query; 
} 

tôi đã không cố gắng và có thể là có thể rằng LINQ to SQL sẽ bị nhầm lẫn bởi mã để tìm giá trị của các loại giá trị nullable. Bạn có thể cần phải viết mã như thế này:

if (courseID != null) 
    { 
     int queryCourseID = courseID.Value; 
     query = query.Where(student => student.CourseID == queryCourseID); 
    } 

Nên thử các hình thức đơn giản đầu tiên mặc dù :)

Tất nhiên, tất cả điều này được một chút khó chịu. Một phương pháp mở rộng hữu ích có thể làm cho cuộc sống ngắn gọn hơn:

public static IQueryable<TSource> OptionalWhere<TSource, TParameter> 
    (IQueryable<TSource> source, 
    TParameter? parameter, 
    Func<TParameter, Expression<Func<TSource,bool>>> whereClause) 
    where TParameter : struct 
{ 
    IQueryable<TSource> ret = source; 
    if (parameter != null) 
    { 
     ret = ret.Where(whereClause(parameter.Value)); 
    } 
    return ret; 
} 

Sau đó, bạn muốn sử dụng nó như thế này:

public IQueryable<Student> FindByAllStudents 
    (int? id, string name, int? courseID, bool? isActive) 
{  
    IQueryable<Student> query = db.Student 
     .OptionalWhere(id, x => (student => student.ID == x)) 
     .OptionalWhere(courseID, x => (student => student.CourseID == x)) 
     .OptionalWhere(isActive, x => (student => student.IsActive == x)); 
    if (name != null) 
    { 
     query = query.Where(student => student.Name.Contains(name)); 
    } 
    return query; 
} 

Sử dụng một hàm bậc cao như thế này có thể gây nhầm lẫn nếu bạn không thực sự thoải mái với nó mặc dù, vì vậy nếu bạn không làm rất nhiều truy vấn như thế này bạn có thể muốn gắn bó với mã dài hơn nhưng đơn giản hơn.

+0

Cảm ơn! Đối với giải pháp đầu tiên, chúng tôi cũng có thể sử dụng nếu (id.HasValue) {sử dụng id.Value} – Vikas

+0

Bạn có thể hướng dẫn tôi sử dụng tìm kiếm toàn văn không? – Vikas

+0

Sử dụng HasValue tương đương với việc sử dụng! = Null. Tôi không biết về việc sử dụng tìm kiếm toàn văn bản với LINQ, tôi sợ. –

Các vấn đề liên quan