2009-04-10 8 views
7

Hola, estoy buscando el mejor método para escribir consultas de Dynamic LINQ.La mejor forma de generar consultas LINQ dinámicas

tengo una función como

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

también podemos escribir db.Students.where (predicado)

o

una consulta como

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

Lo mismo ocurrirá con esta método funciona si no paso ID (es decir, nulo)? es la forma correcta para todos los tipos de datos?

El punto es que la función puede tener todos los valores nulos como un parámetro para la equivalencia de la instrucción select * from.

¿alguien me puede ayudar a crear la mejor consulta con código de muestra?

Respuesta

20

Está bien, no es del todo claro lo que quiere, pero si usted está tratando de añadir solamente en las cláusulas de los parámetros que son no nulo, se podría hacer:

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

No he probado eso, y es posible que LINQ to SQL se confundiría con el código para encontrar el valor de los tipos de valores que aceptan valores. Puede que tenga que escribir código como este:

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

vale la pena probar la forma más simple, aunque primero :)

Por supuesto, todo esto se hace un poco irritante. Un método de extensión útil podría hacer la vida más concisa:

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

Usted sería entonces utilizar de esta manera:

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

Usando una función de orden superior como esto podría ser confuso si usted no es realmente cómodo sin embargo, si no estás haciendo muchas consultas como esta, quizás quieras seguir con el código más largo pero más simple.

+0

Gracias! Para la primera solución, también podríamos usar if (id.HasValue) {que usar id.Value} – Vikas

+0

¿Me puede guiar para usar la búsqueda de texto completo? – Vikas

+0

El uso de HasValue equivale a usar! = Null. No sé cómo usar la búsqueda de texto completo con LINQ, me temo. –

Cuestiones relacionadas