extract one column from a var using linq - c#

i have something like this
var emp = db.Employees.toList();
in my employees table i have emp name, emp id and salary, using linq with lambda expressions, how do i access emp id in some another variable.
I have tried looking up for it, couldn't find a solution which does it using linq with lambda expressions
var employeeLeaves = db.Leaves
.Include("Employee")
.Include("Employee.Manager")
.Where(l => l.Status.Id == 1)
.GroupBy(l => l.Employee.Manager.Id)
.Select(l => l.GroupBy(k=>k.Employee.Id).Select(j=>j.GroupBy(‌​p=>p.GroupId)))
.ToList();
this is the actual query i have,dont ask me how i wrote it..:P now i want to get id column from employeeLeaves and store it in some another variable

It's not entirely clear what you're trying to do, which is why you've got so many answers with different approaches. If you're trying to turn the "collection of employees" into a "collection of IDs" then you want something like this:
var ids = emp.Select(x => x.Id);
Or more directly:
var ids = db.Employees.Select(x => x.Id);
(Optionally with ToList at the end of each of these.)
I would strongly advise you to learn LINQ (and the somewhat-related languages features such as var) thoroughly, from scratch, with the help of a good book or tutorial. Learning bits piecemeal by just finding samples which do something a bit like what you want is not a good approach, IMO.

var empId = db.Employees.Single(x => x.id == 5).Id;

You can use the select. Maybe something like this:
var result=db.Employees
.Select(s=>s.emp_id);

Try this syntax:
var empIds = db.Employees.Select(e=>e.EmpID)

Database.Tablename.Single(x => x.id == anyId)
This should select single row

Related

Find then Sum with IMongoCollection

I am writing an api to sum a column called ViewCount from collection. At the moment, my code is something like this:
var filter = Builders<Post>.Filter.Eq(u => u.IsDelete, query.Param.IsDelete);
IMongoCollection<Post> _posts;
var postViewCount = _posts.Find(filter).ToList().Select(a =>a.ViewCount).Sum();
Result is ok with correct summation but performance is getting slow a lots with only 20k records (about 6s for simple call). If I use like this, it will be very faster (just 200ms) but I cannot put filter in here:
var filter = Builders<Post>.Filter.Eq(u => u.IsDelete, query.Param.IsDelete);
IMongoCollection<Post> _posts;
var postViewCount = _posts.AsQueryable().Sum(x => x.ViewCount);
So my question is how can I handle this case? Thanks guys!
Use .Where(). After calling .AsQueryable() you get IQueryable, so you have all LINQ funtionality available. :)
_posts.AsQueryable().Where(filter).Sum(x => x.ViewCount);
If you use the Agg feature, you will get a faster query.
Good luck with!
var aggregate = new BsonDocument
{
{ "Count", new BsonDocument("$sum", 1) }
};
_posts.Aggregate().Match(filter).Group(aggregate);

Linq query from datasource with where ... like '%%' or ... like '%%'

I'm trying to select all the fields from a db that contains any of the string contained in a list (that could be populated from user).
Is very easy for me to do by pure SQL with a sentence like
WHERE myfield LIKE '%nam%' OR myfield LIKE '%cod%' OR myfield LIKE '%big%'
but I need to do it with C# and Linq. I searched several solutions, some that recommend me to use .Any or .Contains but I didn't get it how to apply to my case :-(
This is the most close result I can achieve:
var query = DataSource.Docs();
...
IList<string> nameFilter = new List<string>() {"nam", "cod", "big"};
query = query.Where(x => x.NomeFile.Contains(nameFilter.FirstOrDefault()));
anyway with this silly code I filter just the elements are containing the first element of my list (the FirstOrDefault let ignore all the others)
Can anybody help me to find the right way?
You're looking for:
query.Where(x => nameFilter.Any(s => x.NomeFile.Contains(s)));
Have you tried this?
query = query.Where(x => nameFilter.Any(n => x.NomeFile.Contains(n)));
or
query = query.Where(x => nameFilter.Any(n => x.NomeFile.IndexOf(n) >= 0));

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);

C# foreach to linq

I was wondering if there wasn't an optimal way for this code.
List<CollectionFormFieldRecord> dataFields = new List<CollectionFormFieldRecord>();
foreach (CollectionRelationModel relation in relations)
{
foreach (var field in visibleFields)
{
if (field.SourceCollectionsID == relation.ChildCollectionID)
dataFields.Add(field);
}
}
When a field (visibleFields) has a SourceCollectionsID that exists in the relations list then the field must be added to a separated list.
I tried somethings with LINQ but didn't know how to compare a property with a property in a list.
You can do this using linq
dataFields = (from relation in relations
from field in visibleFields
where field.SourceCollectionsID == relation.ChildCollectionID
select field).Select(field => field).ToList();
but I do prefer using foreaches instead
The code you showed us has complexity of O(N square). Try to use .Join method, so you will have complexity close to O(N) due to hashing. The code you should use is
dataFields = visibleFields.Join(relations, vF => vF.SourceCollectionsID, r => r.ChildCollectionID, (visibleField, relation) => visibleField).ToList();
For better understand about complexity look at my answer for this question
I can be similar to this
var dataFields = dataFields .Where(f => relations.Any(r => f.SourceCollectionsID ==r.ChildCollectionID))
.ToList()

Categories

Resources