Using this Linq code I get any values corresponding to the search input i.e if I search country = Italy and gender = female I get both employees from Italy and employees who are female but I need it to be more specific.
i.e if I search Country = Italy and Gender = female I need to get female employees from Italy. Please suggest me a Linq code for the same
Also, I have five search inputs (First Name, Last Name, Designation, Country, Gender) so just (&&) only doesn't do the work here!
Here's the code:
List<Employee> Elist = userdb.Employees
.Where(i => i.FirstName == Fn ||
i.LastName == Ln ||
i.Designation == desig ||
i.Country == country ||
i.Gender == gender)
.ToList();
This is a situation where the nature of IQueryable comes in very useful. You can add Where clauses to your query without actually executing anything against the database. The SQL would only be executed when you materialise the data, for example using ToList(). This is called deferred query execution.
So you can write your code like this:
IQueryable<Employee> query = userdb.Employees;
if(!string.IsNullOrEmpty(Fn))
{
query = query.Where(e => e.FirstName == Fn);
}
if(!string.IsNullOrEmpty(Ln))
{
query = query.Where(e => e.LastName == Ln);
}
// etc. etc.
List<Employee> Elist = query.ToList();
Most likely, you are not wanting to include criteria that is not filled in. You would only want to filter by a value if the value exists (or is not null). Use an IQueryable to build your search and then assign it to Elist.
IQueryable<Employee> Query = userdb.Employees;
if (Fn != null) {
Query = Query.Where(i => i.FirstName.Equals(Fn));
}
if (Ln != null) {
Query = Query.Where(i => i.LastName.Equals(Ln));
}
if (desig != null) {
Query = Query.Where(i => i.Designation.Equals(desig));
}
if (country != null) {
Query = Query.Where(i => i.Country.Equals(country));
}
if (gender != null) {
Query = Query.Where(i => i.Gender.Equals(gender));
}
List<Employee> Elist = Query.ToList();
Personally I would use a PredicateBuilder here. A small example, let's say you just have 2 queries:
Expression<Func<Person, bool>> hasFirstName = p1 => p1.FirstName == Fn;
Expression<Func<Person, bool>> hasLastName= p2 => p2.LastName == Ln";
You could build this into a predicate builder like so and keep on expanding using any sort of logic:
var predicate = PredicateBuilder.False<Employee>();
if (!string.IsNullOrEmpty(Fn))
{
predicate = predicate.And(e => e.FirstName == Fn);
}
if (!string.IsNullOrEmpty(Ln))
{
predicate = predicate.And(e => e.FirstName == Ln);
}
var result = userdb.Employees.Where(predicate);
Try this
List<Employee> Elist = userdb.Employees
.Where(i => (Fn == null || i.FirstName == Fn ) &&
(Ln == null || i.LastName == Ln ) &&
(desig == null || i.Designation == desig) &&
(country == null || i.Country == country) &&
(gender == null || i.Gender == gender)
.ToList();
Related
i don't know how to handle this in LINQ
simply i have a searchKey in which i am passing user enter data and it return with rows. but if i am not passing any searchkey it not given any data. i dont want to add contains if searchkey is empty :(
var AppointmentList = (from app in Con.ios_Appointment
where (app.IS_DELETED == false && app.CLINICIANID == appReq.id
&& app.FNAME.Contains(appReq.searchKey.Trim()) || app.LNAME.Contains(appReq.searchKey.Trim()) || app.ADDRESS.Contains(appReq.searchKey.Trim())
)
orderby app.DATE descending
select new
{
app.ID,
app.FNAME,
app.LNAME,
app.DATE,
app.LONGITUDE,
app.LATITUDE,
app.ADDRESS,
app.STATUS,
app.START_TIME
}).Skip(skipRecord).Take(Convert.ToInt32(record)).ToList();
I suggest you use method syntax to easily build the query up programatically:
var query = Con.ios_Appointment.Where(app => !app.IS_DELETED && app.CLINICIANID == appReq.id);
var search = appReq.searchKey.Trim();
if (search != "")
{
query = query.Where(app => app.FNAME.Contains(search) ||
app.LNAME.Contains(search) ||
app.ADDRESS.Contains(search));
}
var appointments = query
.OrderByDescending(app => app.DATE)
.Select(app => new
{
app.ID,
app.FNAME,
app.LNAME,
app.DATE,
app.LONGITUDE,
app.LATITUDE,
app.ADDRESS,
app.STATUS,
app.START_TIME
})
.Skip(skipRecord)
.Take(Convert.ToInt32(record))
.ToList();
You need to use string.IsNullOrWhiteSpace method:
where (app.IS_DELETED == false &&
app.CLINICIANID == appReq.id &&
(string.IsNullOrWhiteSpace(appReq.searchKey) ||
app.FNAME.Contains(appReq.searchKey.is Trim()) || ...
I want to do a query with lambda expression.
My database is a Cosmos DB.
I want to filter for two parameters and one of the two can be null.
For example i want to search for name and lastname and one of both is null.
This is that I am trying:
var result = this._client.CreateDocumentQuery<Person>(
UriFactory.CreateDocumentCollectionUri(_idDatabase, _idCollection), queryOptions)
.Where((f) => f.Name == Name && f.LastName == lastName )
.AsEnumerable()
.ToList();
So this?
var result = this._client.CreateDocumentQuery<Person>(
UriFactory.CreateDocumentCollectionUri(_idDatabase, _idCollection), queryOptions)
.Where((f) => (f.Name == Name || (f.Name == null && f.LastName != null)) && (f.LastName == lastName || (f.LastName == null && f.Name != null))
.AsEnumerable()
.ToList();
try something like this:
var result = this._client.CreateDocumentQuery<Person>(
UriFactory.CreateDocumentCollectionUri(_idDatabase, _idCollection), queryOptions)
.Where(f => f.Name == $"{Name ?? f.Name}") &&
f.LastName == $"{lastName ?? f.LastName}") )
.AsEnumerable()
.ToList();
Maybe you can work with IQueryable:
IQueryable<Person> iPerson = this._client.CreateDocumentQuery<Person>(
UriFactory.CreateDocumentCollectionUri(_idDatabase, _idCollection), queryOptions);
if(Name != null) iPerson = iPerson.Where(f => f.Name == Name);
if(lastName != null) iPerson = iPerson.Where(f => f.LastName == lastName)
return iPerson.AsEnumerable().ToList();
I have 3 tables
eTrip
Country | eProfile
eProfile
Documents (collection of Document)
Documents
Type | ExpiryDate | Country
I am trying to get a collection of eTrips in a search api. There are several conditions that need to be met for an eTrip.
Each employee can hold multiple documents (visas, passports, etc). For an eTrip to be valid we need to make sure the eTrip.Country != the country of a valid passport (future expiry date) document.
How can we write a lambda expression to accomplish this?
The code that I have so far is something like this
var query = context.eTrip.AsQueryable();
query = query.Where(e => e.validTrip == true);
var docs = query.Select(e => e.eProfile.Documents);
foreach (Documents d in docs)
{
if (d.DocumentTypeCode == "Passport" && d.ExpiryDate != null && d.ExpiryDate > DateTime.Now)
{
query = query.Where(e => e.Country != d.Country);
}
}
I need to write the filter for the country now and I am not sure how we can do it for a collection.
you can extend your Where clause with an Any subquery on Documents
query = query.Where(e => e.validTrip == true && e.eProfile.Documents.Any(a=>a.DocumentTypeCode == "Passport" && a.ExpiryDate.HasValue && a.ExpiryDate.Value > DateTime.Now && e.Country!=d.Country));
Try that:
// your part
var query = context.eTrip.AsQueryable();
query = query.Where(e => e.validTrip == true);
var docs = query.Select(e => e.eProfile.Documents);
// get countries for which there are no documents with future date
var myCountryQuery = query.Where(x => !docs
.Where(d => d.DocumentTypeCode == "Passport" && d.ExpiryDate != null && d.ExpiryDate > DateTime.Now)
.Any(d => d.Country != x.Country)
);
I have a search form which i want to use to search a database for data. The searchbox has 4 checkboxes and 1 textfield. The problem is how do i build the linq query considering i dont know beforehand what textboxes the user will check for filtering the search. What i have so far is:
[HttpPost]
public ActionResult search(string ulv, string bjorn, string jerv, string gaupe)
{
var query = (from o in db.observasjonene select o);
if (ulv != null)
{
query = query.Where(o => o.art == ulv);
}
if (bjorn != null)
{
query = query.Where(o => o.art == bjorn);
}
if (jerv != null)
{
query = query.Where(o => o.art == jerv);
}
if (gaupe != null)
{
query = query.Where(o => o.art == gaupe);
}
IEnumerable ls = query.ToList();
return Json(ls, JsonRequestBehavior.AllowGet);
}
The problem with the "where" clause is that if a condition is true, it overwrites the results from the earlier condition. I guess i need an "or" statement or something..
If I have understood your question correctly, you want to check if art equals to any of provided values. You can combine those values into collection and check if collection contains art value:
var values = new [] { ulv, bjorn, jerv, game }.Where(v => v != null);
var query = from o in db.observasjonene
where values.Contains(o.art)
select o;
EF translates Contains into SQL IN operator.
I'm using two approaches in this case:
Build dynamic query:
var q = DB.Invoices.AsQueryable();
if (isPresented != null)
q = q.Where(iv => iv.IsPresented == isPresented);
if (ID != null)
q = q.Where(iv => iv.ID == ID.Value);
...........................
return from iv in q
orderby iv.DueDate descending
select iv;
Use Union to combine search results:
var q1 = db.FeeInvoice.Where(fi => [QUERY1]));
if (isPresented != null)
{
var q2 = db.FeeInvoice.Where(fi =>[QUERY2]));
q1.Union(q2);
}
if (ID != null)
{
var q3 = db.FeeInvoice.Where(fi =>[QUERY3]);
q1.Union(q3);
}
...........................
You are comparing all the parameters value to single column in the query ie. art (see you have written same column name in each where condition) . I'm not sure why are you doing so? you can simply take single parameter which compare the value like this
public ActionResult search(string value)
{
query = query.Where(o => o.art == value);
}
or if it is by mistake and you want to apply where condition along with multiple column then you can try something like this
query=query.Where(o => (o.art == ulv || ulv == string.Empty) && (o => o.bjorn == bjorn || bjorn=string.empty) && (o.jerv == jerv || jerv == string.Empty) && (o.gaupe == gaupe || gaupe == string.Empty));
Note: I assume your column name as your parameters name.
There's some faster method than this to find all person with some conditions?
if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(lastname) && !String.IsNullOrEmpty(phone))
{
List<Person> newList = List.FindAll(s => s.Name == name && s.Surname == lastname && s.Phone == phone);
}
else if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(lastname))
{
List<Person> newList = List.FindAll(s => s.Name == name && s.Surname == lastname);
}
etc.
Your version is likely the fastest option at runtime. The List<T>.FindAll predicate you created is efficient, since it does the fewest checks.
However, you could use LINQ to make the code simpler and more maintainable:
IEnumerable<Person> people = List; // Start with no filters
// Add filters - just chaining as needed
if (!string.IsNullOrWhitespace(name) && !string.IsNullOrWhitespace(lastname))
{
people = people.Where(s => s.Name == name && s.Surname == lastname);
if (!string.IsNullOrWhitespace(phone))
people = people.Where(s => s.Phone == phone);
}
//... Add as many as you want
List<Person> newList = people.ToList(); // Evaluate at the end
This will be far more maintainable, and likely be "fast enough", since filtering is typically not done in a tight loop.
I'd rewrite this way just to make it easier to read:
if (!String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(lastname)) {
if (!String.IsNullOrEmpty(phone))
{
List<Person> newList = List.FindAll(s => s.Name == name && s.Surname == lastname && s.Phone == phone);
}
else
{
List<Person> newList = List.FindAll(s => s.Name == name && s.Surname == lastname);
}
}