ASP.NET MVC 4 MvcMovie Tutorial Filter query by multiple search criteria - database

I was going through the MvcMovie Tutorial and I was trying to modify the SearchIndex() call in the MoviesController to search by multiple criteria. The tutorial shows you how to search by title and genre using the following code:
var movies = from m in db.Movies
select m;
if (!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}
if (string.IsNullOrEmpty(movieGenre))
return View(movies);
else
{
return View(movies.Where(x => x.Genre == movieGenre));
}
So if I read this right they return all movies then filter on Genre. That would be fine for a dual case but when you add in a 3rd or 4th search criteria you would then increase the amount of if statement calls by a factor of 2 (to the n) - 1 cases. This would get very unruly if for say you had 10 or so columns to search by.
I tried to use something a little more straight forward like:
var movieQry = from m in db.Movies
where ((m.Title !=null && m.Title == searchString) ||
(m.Rating != null && m.Rating == movieRating) ||
(m.Genre != null && m.Genre == movieGenre))
select m;
but that would not return anything when you first visit the page and only works for a single filter (if I select the Genre - I get good results but not when I select Genre and Rating) and I get nothing returned when I enter a search term for Title.
Is there an easier way to accomplish? (At some point I will need to be able to search on dozens of filters for a project I will be writing... and I have other questions about how to search database for entries but for not this will get me moving in the right direction).

if you want to include the column in the criteria if it is not null then try following:
string Title = Request.QueryString["Title"];
string Rating= Request.QueryString["Rating"];
string Genre = Request.QueryString["Genre"];
var movieQry = from m in db.Movies
where ((string.IsNullOrEmpty(Title) ? true : m.Title == Title ) &&
(string.IsNullOrEmpty(Rating) ? true : m.Rating == Rating ) &&
(string.IsNullOrEmpty(Genre) ? true : m.Genre == Genre ))
select m;

Behnam was kind of on the right track. I modified the code as follows:
var movieQry2 = from m in db.Movies
where ((string.IsNullOrEmpty(searchString) ? true : m.Title.Contains(searchString)) &&
(string.IsNullOrEmpty(movieRating) ? true : m.Rating == movieRating) &&
(string.IsNullOrEmpty(movieGenre) ? true : m.Genre == movieGenre))
select m;
This works and gives good results. Sorry Behnam can't give you an accepted answer but I did tick it up as being useful. Thanks for pointing me in the right direction.

Try this:
var movieQry = db.Movies
.Where(x=> (Title == null || x.Title ==Title)
&& (Rating == null || x.Rating == Rating)
&& (Genre == null || x.Genre == Genre))
.ToList();
For other paging and sorting see MVC multiple field search

Related

Move channel from Category 1 to Category 2 with roles

how do i make the channel move category using roles?
example:
Category 1 (roles 1)
My Channel
Category 2 (roles 2)
as people have pointed out in the comments, this is a really bad question, as stack overflow is for help with issues, not help for writing code. Also try to make your question more descriptive, what have you tried, etc.
It's hard to tell exactly what you mean since the question's less than 20 words long, but moving a channel inside a category should be done like this:
let category = server.channels.cache.find(c => c.name == "My Category" && c.type == "category"),
channel = server.channels.cache.find(c => c.name == "text-channel" && c.type == "text");
if (category && channel) channel.setParent(category.id);

Linq - Query on 2 Lists Optimization

I am having 2 Lists & I am querying on this 2 List. Both the List are populated with huge data. So the query is taking long time.
When I usually face this performance issue, I simply convert SQL queries & run them directly & get the result in a datatable. But this time I cannot do this as these 2 are not tables but Lists of Models.
How to Optimize this Query or what else should i do?
Code :-
List<TempInOut> listTempInOut = new List<TO_TempInOut>();
List<ShiftSchedule> tempShiftSch = new List<TO_TempInOut>();
var data = (from B in tempShiftSch
from C in listTempInOut
where
B.CompanyId == companyId &&
C.CompanyId == companyId &&
B.EmployeeId == C.EmployeeId &&
C.InDate >= StrOutStart &&
C.InDate <= StrOutEnd &&
B.ShiftId == item.ShiftCode &&
B.ShiftDate == tempInputDate
select new
{
C.EmployeeId,
C.InDate,
C.Time_Date1
}).ToList();
Implement an IEqualityComparer for your types, use HashSet for each collection, and use the HashSet.Intersect method to get your output.
You can simplify your query to two stepsand compare time.
I am thinking of something like that.
var listTempInOutResult = listTempInOut.Where(C => C.CompanyId == companyId
&& C.InDate >= StrOutStart
&& C.InDate <= StrOutEnd);
var employessIds = listTempInOutresult.Select(x => x.EmployeeId).ToList();
var data = tempShiftSch.Where(B => employessIds.Contains(B.EmployeeId)
&& B.CompanyId == companyId
&& B.ShiftDate == tempInputDate
&& B.ShiftId == item.ShiftCode)
.Select(C=> new
{
C.EmployeeId,
C.InDate,
C.Time_Date1
}).ToList();
if you are working with iqueryable it would be better to use joins.
see this StackOverflow question

Get the List object to compare with Date Time but am not getting greater values in the List in wpf

I want to compare the List Object with Date Time.but getting the same date values also , But I don't want same date time records. I need only maximum date values only.
List<ExpImpSurplus_Review> imprtSurplusReview = JsonConvert.DeserializeObject<List<ExpImpSurplus_Review>>(str);
TableName = "Surplus_Review";
lastImpDate = GetLatestImportedTime(TableName);
if (lastImpDate != Convert.ToDateTime("1/1/0001 12:00:00 AM"))
{
imprtSurplusReview = imprtSurplusReview.Where(p => (p.DateModified > lastImpDate && p.DateModified != null) || (p.DateCreated > lastImpDate && p.DateModified == null)).ToList();
}
Any help will be appreciated ?
I'm not entirely sure what your problem is, but I notice two things:
(p.DateModified > lastImpDate && p.DateModified != null) -- you should be checking for null first, i.e. before the first check. The && operator evaluates from the left
(p.DateCreated > lastImpDate && p.DateModified == null) -- you're checking for DateModified being populated, but you're using DateCreated in the comparison, which I assume is a bug.

Linq contains()

I am implementing a search button, that pulls all products having the words a user will be entering in a textbox.
Say the user types : Shoes.
I coded my linq to query the database to return all product containing the keyword in any of its columns as below
var products = from x in db.Products
where x.SupplierId == loggedInUser &&
( x.Status.ToString().Contains(searchCriteria) ||
x.SupplierCode.Contains(searchCriteria) ||
x.ProductId.ToString().Contains(searchCriteria) ||
x.Barcode.Contains(searchCriteria) ||
x.Description.Contains(searchCriteria) ||
x.ProposedActiveDate.ToString().Contains(searchCriteria) ||
x.VATRate.ToString() .Contains(searchCriteria) )
select x;
Problem ?
I do not get any product from the database(There is the product in the database).
What did I do wrong ?
I think you have the order wrong...
if the user had typed shoes, boots then you need to split the search terms "shoes" and "boots" and add them to a list<> and then do the following
SearchTermsList.Contains(x.Status.ToString()) || SearchTermsList.Contains(x.SupplierCode)
var searchCriteriaLowerCase = lowerCase.ToLower();
var products = db.Products.Where(x=> x.SupplierId == loggedInUser &&
x.Status.ToLower().ToString().Contains(searchCriteriaLowerCase) ||
x.SupplierCode.ToLower().Contains(searchCriteriaLowerCase) ||
x.ProductId.ToLower().ToString().Contains(searchCriteriaLowerCase) ||
x.Barcode.ToLower().Contains(searchCriteriaLowerCase) ||
x.Description.ToLower().Contains(searchCriteriaLowerCase) ||
x.ProposedActiveDate.ToString().Contains(searchCriteria) ||
x.VATRate.ToLower().ToString().Contains(searchCriteria) ).ToList();
This may work.
I think you are not executing the query.
use like this.
var products = from x in db.Products
where x.SupplierId == loggedInUser &&
( x.Status.ToString().Contains(searchCriteria) ||
x.SupplierCode.Contains(searchCriteria) ||
x.ProductId.ToString().Contains(searchCriteria) ||
x.Barcode.Contains(searchCriteria) ||
x.Description.Contains(searchCriteria) ||
x.ProposedActiveDate.ToString().Contains(searchCriteria) ||
x.VATRate.ToString() .Contains(searchCriteria) )
.ToList();

lambda expression for a query on two tables that returns records from one table

I have two tables
TableA (articles)
int id
int Type
string name
and
TableB (compatibles)
int linked_ID
int tableA_ID
TableA records:
id=1, Type=0, name="ArticleA"
id=2, Type=1, name="ArticleB"
id=3, Type=2, name="ArticleC"
id=4, Type=1, name="ArticleD"
TableB records:
linked_ID= 1, tableA_ID=2
linked_ID= 1, tableA_ID=3
linked_ID= 1, tableA_ID=4
TableB has a list of arcicels that are compatible to a certain article. I am quite new to queries (didn't need them in my projects yet). But as C# and WPF allow some pretty cool automation with Binding I would like to add a binding that returns the following:
Give me all articles that are of Type 1 and compatible to my selected article (id=1).
The simple part of it works well (articles has a list of all articles):
private ObservableCollection<Article> _articles =
new ObservableCollection<Article>();
[fill it with the available articles]
and then:
comboBoxArticles.ItemsSource =
_articles.AsBindable().Where( c => c.Typ == 0 );
How can I extend the Where clause to query another table?
Thanks a lot in advance.
It appears as if you want to "join" two "tables" using Linq. Here is something to get you started:
comboBoxArticles.ItemsSource =
from article in _articles
from compatible in _compatibles
where article.Type == 0 && && article.id == compatible.tableA_ID && compatible.linked_ID == 1
select article;
... or in method chain...
comboBoxArticles.ItemsSource = _articles
.SelectMany(article => _compatibles, (article, compatible) => new {article, compatible})
.Where(#t => #t.article.Type == 0 && #t.article.id == #t.compatible.tableA_ID && #t.compatible.linked_ID == 1)
.Select(#t => #t.article);

Resources