When dealing with user select-able search criteria you will need to code for the possible selections. When dealing with building searches I recommend using the Fluent syntax over the Linq QL syntax as it builds an expression that is easy to conditionally modify as you go. From there you can use a Predicate & PredicateBuilder to dynamically compose your WHERE condition.
Jacques solution will work, but the downside of this approach is that you are building a rather large & complex SQL statement which conditionally applies criteria. My preference is to conditionally add the WHERE clauses in the code to ensure the SQL is only as complex as it needs to be.
If you want to do something like a smart search (think Google with one text entry to search across several possible fields)
var whereClause = PredicateBuilder.False<StudentData>();
int id;
DateTime date;
if(int.TryParse(searchTxt, out id))
whereClause = whereClause.Or(x => x.SID == id);
else if(DateTime.TryParse(searchTxt, out date))
whereClause = whereClause.Or(x => x.BirthDate == date);
else
whereClause = whereClause.Or(x => x.FirstName.Contains(searchTxt));
var data = db.StudentData
.Where(whereClause)
.Select(a => new
{
ID = a.SID,
Birthdate = a.BIRTHDTE,
FirstName = a.FNAMES,
PreviousName = a.PREVSURNAME,
EntryQualAwardID = a.EntryQuals.ENTRYQUALAWARDID,
AwardDate = a.EntryQuals.AWARDDATE
}).ToList();
This does some basic evaluations of the search criteria to see if it fits the purpose of the search. I.e. if they can search by name, date, or ID and IDs are numeric, we only search on an ID if the criteria was numeric. If it looked like a date, we search by date, otherwise we search by name. (and potentially other searchable strings)
If they can search for ID, FirstName, and BirthDate and enter one or more of those as separate entry fields (Search criteria page) then based on which entries they fill in you can either pass separate nullable parameters and do the above based on what parameters are passed, or pass a list of search values with something like an Enum for which value was searched for:
I.e. by parameters:
private void ByParameters(int? id = null, DateTime? birthDate = null, string name = null)
{
var whereClause = PredicateBuilder.False<StudentData>();
if(id.HasValue)
whereClause = whereClause.Or(x => x.SID == id.Value);
if(date.HasValue)
{
DateTime dateValue = date.Value.Date;
whereClause = whereClause.Or(x => x.BirthDate == dateValue);
}
if (!string.IsNullOrEmpty(name))
whereClause = whereClause.Or(x => x.FirstName.Contains(name));
// ....
}
If the number of parameters starts to get big, then a custom type can be created to encapsulate the individual null-able values. I.e.:
[Serializable]
public class SearchCriteria
{
public int? Id { get; set; }
public DateTime? BirthDate { get; set; }
public string Name { get; set; }
}
private void ByParameters(SearchCriteria criteria)
{
// ....
}
Or you can compose a more dynamic parameter list object with a criteria type and value but it starts getting more complex than it's probably worth.
b.SID,c.SIDandd.SID?