Reputation: 299
I have four buttons in a web form and their purpose is to load the first, previous, next and last record respectively. They do so by taking the current ID loaded in the form and acting as required. I am using Linq to SQL. Below is the code I was using for the NEXT record which functions fine if i want to load the next record by ID.
var dx = new DataModelDataContext();
List<Dog> dogList = dx.Dogs.AsEnumerable().ToList();
try
{
return
dogList.SkipWhile(x => x.Id != dogId).Skip(1).FirstOrDefault().Id.ToString(
CultureInfo.InvariantCulture);
}
catch
{
return null;
}
I repeat, for the previous scenario this code works fine.
The scenario has changed in such a way that I now have to retrieve the records using the previously mentioned buttons according to a dropdown list which contains the properties of the form (FirstName,LastName,Gender etc...) So its no longer a function with the intent of locating the next record via the ID.
I was thinking of creating a LoadNextRecord(searchParameter,TextboxValue) in order to locate the next record according to the property specified from the dropdown list.
However, is it possible to specify dynamically with which property I want to compare my data?
example: x =>x.[searchParameter] != textboxvalue
I know that this is possible using Dynamic sql... however I would like to know whether it is possible using LINQ.
Upvotes: 2
Views: 420
Reputation: 33252
It is possible if you use Dynamic Linq. By downloading the sample here, you'll find a file in the zip at this path: LinqSamples\DynamicQuery\DynamicQuery\dynamic.cs
. By adding that file and the proper using you have some IQueryable
extension methods that allow you to express contitions in string format. In the zip there is examples on how to use anyway. With this solution you are stuck with the so called "magic strings", but not so "magic" since the linq expression is compiled behind the scenes.
Upvotes: 4
Reputation: 2139
edit** sorry, misread the question, reflection would be better.
edit***
actually, no, you could bind the combobox to a set of objects which have predicate properties, then onchange / button event (whatever you use to go to next record) you could get the object out of the combobox, and use its predicate inside the linq method.
It does mean maintaining a set of objects for each property you want to skip on, but you'll have to do a bit of work if you wanted to add another one to the comobox anyway.
Dictionary<string, Predicate<YourType>> filters = new ...
filters.Add("YourProp", x => x.yourProp == "blah blah");
Combobox box = new ...
box.ValueMember = "Value";
box.DispayMember = "Key";
box.DataSource = filters;
var pred = box.SelectedValue as Predicate<YourType>;
if (pred != null)
{
GoToNextRecord(pred);
}
then in the linq method...
dogs...Skip(pred)...;
Upvotes: 0
Reputation: 10515
You could use reflection
var dx = new DataModelDataContext();
List<Dog> dogList = dx.Dogs.AsEnumerable().ToList();
string PropetyToCheck = "MyProperty";
PropertyInfo property = typeof(Dog).GetProperty(PropetyToCheck);
try
{
return
dogList.SkipWhile(x => property.GetValue(x, null) != dogId).Skip(1).FirstOrDefault().Id.ToString(
CultureInfo.InvariantCulture);
}
Upvotes: 1
Reputation: 10605
You could put an interface on your base class that exposes a searchParameter() member.
var searchValue = dogId;
return
dogList.SkipWhile(x => x.searchParameter() != searchValue).Skip(1).FirstOrDefault().Id.ToString(CultureInfo.InvariantCulture);
Upvotes: 1