Linq Order by alphabetical - c#

I got a product table and want to get datas sort by alphabetical. But when i write this query they are still coming by id. I check a lot of page in google but cant find any source.
var product = Db.tablename
.Where(s => s.colum == DropDownList2.SelectedValue)
.OrderBy(s=> s.Name);

This query
var product = Db.tablename
.Where(s => s.colum == DropDownList2.SelectedValue)
.OrderBy(s=> s.Name);
will not be executed until it is asked to. So you have to change it to the following one:
var product = Db.tablename
.Where(s => s.colum == DropDownList2.SelectedValue)
.OrderBy(s=> s.Name).ToList();
The reason why that happens is that actually you just have declared a query. I mean you haven't executed it. That's the nature of LINQ queries, which in technical terms is called deffered execution. On the other hand if you call the ToList() method at the end of your query, you will trigger the immediate execution of this query and it's result will be a List of the same type with s.Name.

You must use ToList to execute the sort.
var product = Db.tablename
.Where(s => s.colum == DropDownList2.SelectedValue)
.OrderBy(s=> s.Name).ToList();
The order by does nothing, just executes the query, the ToList will do the sort for the original query.

Related

Where Clauses Causing Errors in LINQ

I am trying to return rows based on a search term that may include a space.
The code below is is generating the following error. I cannot figure out what I'm doing wrong, any suggestions?
Local sequence cannot be used in LINQ to SQL implementations of query
operators except the Contains operator.
var searchTerms = term.Split(' ').ToList();
var surveys = (from s in dc.BasicNeedsSurveys where s.Hidden ==
false orderby s.CreatedOn descending select s)
.Where(x => searchTerms.Any(y => y.Contains(x.FirstName))
|| searchTerms.Any(y => y.Contains(x.LastName))
|| searchTerms.Any(y => y.Contains(x.FEMANumber)));
according to the error message you are using linq to sql (or EF). linq to sql generate SQL query behind the scene, and you cant use a local var such as searchTerms inside an sql query. if i understand it correctly and dc.BasicNeedsSurveys is actually a data base entity (like in entity framework for example) your solution will be to first execute the sql query and then run the test if substring of search terms contains the search result. ToList is one function that can do that.
var searchTerms = term.Split(' ').ToList();
var surveys = (from s in dc.BasicNeedsSurveys where s.Hidden ==
false orderby s.CreatedOn descending select s)
.ToList()
.Where(x => searchTerms.Any(y => y.Contains(x.FirstName))
|| searchTerms.Any(y => y.Contains(x.LastName))
|| searchTerms.Any(y => y.Contains(x.FEMANumber)));
of course, there might be better ways to do that with better performance since here you are filtering the results only after you read all of them from the hard drive, but there is really not enough information in the question for that

Retrieving property from first item with LINQ

Is there a simpler way to write this query in Linq:
var prioritiy = db.Requirements.Where(r => r.ID == rowID).Select(r => r.Priority).First();
If you mean "simpler" as in "less code", your self-answer is already the most compact:
db.Requirements.First(r => r.ID == rowID).Priority;
If you mean "simpler" as in "less database overhead", then your original version is slightly better:
db.Requirements.Where(r => r.ID == rowID).Select(r => r.Priority).First();
Why? As #IvanStoev pointed out in the comments, LINQ execution is deferred until you call a "finishing" method like First(). If you're using SQL on the backend, the second example will be translated into a SQL statement that retrieves only the Priority field from the database, whereas the first example will retrieve all fields for the matching row.
This is, IMO, firmly in the realm of unnecessary micro-optimizations, unless this code runs millions of times or the full database object has tons of columns. Unless you're doing something crazy, just use the style that you like!
Never mind. I just figured out that by applying First() initially, I return an object which contains the property I'm looking for. The code turns into:
var priority = db.Requirements.First(r => r.ID == rowID).Priority;
a safer version in Visual Studio 2015
var priority = db.Requirements.FirstOrDefault(r => r.ID == rowID)?.Priority;
of if you call that often, you can use a LookUp
var lookup = db.Requirements.ToLookup(r => r.ID, r => r.Priority);
var priority = lookup[rowID].FirstOrDefault();

NOT IN Condition in Linq

I have a simple scenario.I want to list out all the employees except the logged in user.
Similar SQL Condition is
select * from employee where id not in(_loggedUserId)
How can I acheive the above using LINQ.I have tried the following query but not getting the desired list
int _loggedUserId = Convert.ToInt32(Session["LoggedUserId"]);
List<int> _empIds = _cmn.GetEmployeeCenterWise(_loggedUserId)
.Select(e => e.Id)
.Except(_loggedUserId)
.ToList();
Except expects argument of type IEnumerable<T>, not T, so it should be something like
_empIds = _cmn.GetEmployeeCenterWise(_loggedUserId)
.Select(e => e.Id)
.Except(new[] {_loggedUserId})
.ToList();
Also note, this is really redundant in the case when exclusion list contains only one item and can be replaces with something like .Where(x => x != _loggedUserId)
Why not use a very simple Where condition?
_empIds = _cmn.GetEmployeeCenterWise(_loggedUserId).Where(e=>e.Id != _loggedUserId).ToList();
The title of your question is how to perform a not in query against a database using LINQ. However, as others have pointed out your specific problem is better solved by a using users.Where(user => user.Id != loggedInUserId).
But there is still an answer on how to perform a query against a database using LINQ that results in NOT IN SQL being generated:
var userIdsToFilter = new[] { ... };
var filteredUsers = users.Where(user => !userIdsToFilter.Contains(user.Id));
That should generate the desired SQL using either Entity Framework or LINQ to SQL.
Entity Framework also allows you to use Except but then you will have to project the sequence to ID's before filtering them and if you need to original rows you need to fetch them again from the filtered sequence of ID's. So my advice is use Where with a Contains in the predicate.
Use LINQ without filtering. This will make your query execute much faster:
List<int> _empIds = _cmn.GetEmployeeCenterWise(_loggedUserId)
.Select(e => e.Id).ToList();
Now use List.Remove() to remove the logged-in user.
_empIds.Remove(_loggedUserId);

IQueryable queried data count

I am trying to get the count of the items as I'm applying a query to a IQueryable.
I'am trying to do it like:
this.lblSth.Text = new Repository<Sth>().GetAll().Where(p => p.PersonId == personId).ToList().Count().ToString();
I think this gets all the data across the condition and takes the objects, then it takes the count; so I'm curious if for example I'd just take the Id columns and cast it to the list or some other smart way; that count operation would be quicker?
Info: GetAll() => It's a repository pattern method that returns IQueryable objects T from linqToSql data entity.
I'm open to all types of different ideas. Thanks
I think the call to Where and ToList is redundant.
see below.
this.lblSth.Text = new Repository<Sth>().GetAll().Count(p => p.PersonId == personId).ToString();
If you want to do this quicker, just don't call ToList():
this.lblSth.Text = new Repository<Sth>().GetAll()
.Where(p => p.PersonId == personId)
.Count()
.ToString();
This way, (assuming it's an SQL-backed IQueryable<T>) it will execute a query like SELECT COUNT(*) FROM …, not SELECT * FROM … like your approach. And this query should be much faster.
ToList() will execute the query and turn your IQUeryable into IEnumerable. I would call the count on the where clause. That way the Count will become part of the end query

Issue using Where method in LINQ

Consider this line of code:
List<SIDB_TransactionInformation> transaction = SIDB.SIDB_TransactionInformations
.Where(k => k.iscurrent == true & k.objectid == SIDB.func_GetObjectID("dbo.SIDB_Module")).ToList();
List<SIDB_Module> module = SIDB.SIDB_Modules
.Where(k => k.moduleid == transaction
.Where(j => j.transactionid == k.moduleid)
.SingleOrDefault().transactionid).ToList();
I do have 2 invocation of where method in different collection. First i distinct my list via iscurrent and objectid after that I do have other invocation of where method (for SIDB_Modules) to distinct the list via moduleid where in the the values refer to the transactionid of my previous list. Now i have an error message like this Local sequence cannot be used in LINQ to SQL implementation of query operators except the Contains() operator.
sorry i'm new in lambda expression. need help badly
I think this is what you're looking for
List<SIDB_Module> module = SIDB
.SIDB_Modules
.Where(k => transaction.Any(j => j.transactionid == k.moduleid))
.ToList();
Make a list of SIDB_Modules where there is a transaction whose transactionid is equal to the moduleid. LINQ to Sql might have an issue with Any, I don't remember, if it does you can rewrite it with an extra step like this
var transactionIds = transaction.Select(j => j.transactionid);
List<SIDB_Module> module = SIDB
.SIDB_Modules
.Where(k => transactionIds.Contains(k.moduleid))
.ToList();
If performance is an issue you might consider going with the second method and putting transactionIds into something that implements ISet<T> and has a constant time lookup.
Well, it looks like you're trying to do a join between SIDB_TransactionInformations and SIDB.SIDB_Modules. If so, try
var objectID = SIDB.func_GetObjectID("dbo.SIDB_Module");
List<SIDB_Module> modules = (from module in SIDB.SIDB_Modules
join transaction in SIDB.SIDB_TransactionInformations on module.moduleid equals transaction.transactionid
where transaction.iscurrent && transaction.objectid == objectID
select module).ToList();

Categories

Resources