i have many to many relationship between employee and group. following linq statement
int[] GroupIDs = {6,7};
var result = from g in umGroups
join empGroup in umEmployeeGroups on g.GroupID equals empGroup.GroupID
where GroupIDs.Contains(g.GroupID)
select new { GrpId = g.GroupID,EmployeeID = empGroup.EmployeeID };
returns groupid and the employeeid. and result is
GrpId | EmployeeID
6 | 18
6 | 20
7 | 19
7 | 20
I need to remove the rows for which the employeeid is repeating e.g. any one of the row with employeeid= 20
Thanks
Okay, if you don't care which employee is removed, you could try something like:
var result = query.GroupBy(x => x.EmployeeId)
.Select(group => group.First());
You haven't specified whether this is in LINQ to SQL, LINQ to Objects or something else... I don't know what the SQL translation of this would be. If you're dealing with a relatively small amount of data you could always force this last bit to be in-process:
var result = query.AsEnumerable()
.GroupBy(x => x.EmployeeId)
.Select(group => group.First());
At that point you could actually use MoreLINQ which has a handy DistinctBy method:
var result = query.AsEnumerable()
.DistinctBy(x => x.EmployeeId);
Related
I am looking for help with a LINQ statement; Firstly, I have a List which has two columns, these are the users account and their access level.
AccountID | Access
-------------------
1374 | 4
1832 | 1
1383 | 1
1182 | 2
The above list is obtained from the session cache.
List<myUsers> users = new List<myUsers>();
users = myUsers.GetFromUserSession();
What I would now like to do is create a new list which contains only the list of AccountID's whose access is greater than or equal to 3. Here is where I've been playing but i can't quite work out how to include the Where statement properly. For example the intellisense doesn't let me introduce something like x.Access.
List<int> adminList = myUsers.Select(x => x.AccountID).Where(x => x >= 3).Distinct().ToList()
I'm now at the point where i'm just tinkering with it until something works, but thought I would ask the community as i'm sure this is something very easy for some folk to accomplish.
your query is wrong structured
var admins = myUsers.Where(x => x.Access >= 3)
.Select(x => x.AccountID)
.Distinct()
.ToList()
By doing the select before the where you only get the AccountID from that point on so you apply the where to the AccountID.
it should be
List<int> adminList =myUsers.Where(x => x.Access >= 3).Select(x => x.AccountID).Distinct().ToList()
You must use the Wherefirst and then select what you want from myUsers(the AccountID):
List<int> adminList = myUsers
.Where(x => x.Access >= 3)
.Select(x => x.AccountID) // here x is still the myUsers instance
.Distinct()
.ToList();
I have a datagridview with two columns like this:
group | quantity
------------------------
chest | 3
legs | 7
back | 2
chest | 1
back | 5
legs | 2
What I'm trying to do is to get the sum of distinct group to a list and use that list for populate another datagridview.
So the result must be in this example:
chest | 4
legs | 9
back | 7
I've tried some linq query code but without any success.
How can I do it?
Here's some Linq queries I tried:
List<string> vv = dataGridView1.Rows.Cast<DataGridViewRow>()
.Where(x => !x.IsNewRow)
// either..
.Where(x => x.Cells[7].Value != null)
//..or or both
.Select(x => x.Cells[7].Value.ToString())
.Distinct()
.ToList();
dataGridView6.DataSource = vv;
EDIT
the group column is being auto filled after a selection of another column combobox, the quantity is filled manually. For the group by I found this code and works but throw an error if a cell is empty:
var Sums = dataGridView1.Rows.Cast<DataGridViewRow>()
.GroupBy(row => row.Cells[7].Value.ToString()) // group column
.Select(g => new { User = g.Key, Sum = g.Sum(row => Convert.ToInt32(row.Cells[1].Value)) });
dataGridView6.DataSource = Sums.ToList();
ok, here the solution that works:
var Sums = dataGridView1.Rows.Cast<DataGridViewRow>()
.Where(row => row.Cells[7].Value != null)
.GroupBy(row => row.Cells[7].Value.ToString()) // group column
.Select(g => new { User = g.Key, Sum = g.Sum(row => Convert.ToInt32(row.Cells[1].Value)) }); // quantity column
dataGridView6.DataSource = Sums.ToList();
Lets say I've table with the structure as below:
MyRow:
Id Name Date
1 A 2015/01/01
2 B 2015/01/01
3 C 2015/01/02
4 A 2015/01/03
5 B 2015/01/03
6 A 2015/01/02
7 C 2015/01/01
Using EF I would like to get list of MyRow which would contain elements with distinct names and newest date so in this case it would be:
4 A 2015/01/03
5 B 2015/01/03
3 C 2015/01/02
I started with something like this:
var myRows = context.MyRows.GroupBy(mr => mr.Name).Select(..now wth with max..)
Order each group and take the last of each.
Or since EF doesn't (last time I checked) support Last(), order each group in reverse and take the first:
var myRows = context.MyRows
.GroupBy(mr => mr.Name)
.Select(grp => grp.OrderByDescending(mr => mr.Date).First());
var data = context.MyRows.Group(p => p.Name)
.Select(g => new {
Type = g.Key,
Date = g.OrderByDescending(p => p.Date)
.FirstOrDefault()
}
So Currently I have this TrackingInfo class which contains an ID and a list of EmailActionIDs, which is an int.
I have a List Of this class which the data looks like:
ID, | EmailActions
_______________
A | 1, 3, 5
B | 3, 5, 6
C | 2, 4, 6
I'm trying to write a Linq Statement To convert this into A list of IDs grouped by each individual value in the list.
So the Results Set would look like:
ID | Values
_______________
1 | A
2 | C
3 | A, B
4 | C,
5 | A, B
6 | B, C
I can't figure out how I would write the group by can anyone give me some insight.
DistinctValues = new List<int> {1,2,3,4,5,6};
TrackingInfo.Groupby(t => DistinctValues.foreach(d =>
t.EmailActions.Contains(d))).Tolist()
This ofcourse isn't working any suggestions on how to do this using Linq
Its easy enough to get a distinct list of EmailActions
var distinctEmailActions = items.SelectMany(i => i.EmailActions).Distinct();
Then pivoting this is a little complex, but here it is:
var result = distinctEmailActions.Select(e => new {
ID=e,
Values = items.Where(i => i.EmailActions.Contains(e)).Select(i => i.ID)
});
Live example: http://rextester.com/CQFDY66608
What you're looking for is SelectMany, but it's easier to use query syntax here:
var result = from item in source
from action in item.EmailActions
group item.ID by action into g
select new { ID = g.Key, Values = g.ToList() }
You can do it by first generating a range using Enumerable.Range, and then matching EmailActions, like this:
var res = Enumerable.Range(1, 6)
.SelectMany(v => TrackingInfo.Where(info => info.EmailActions.Contains(v)).Select(info => new { Id, Value = v }))
.GroupBy(p => p.Value)
.Select(g => new {
Id = g.Key
, Values = g.Select(p => p.Id).ToList()
});
You can achieve this using SelectMany & GroupBy like this:-
var result = tracking.SelectMany(x => x.EmailActionIDs,
(trackObj, EmailIds) => new { trackObj, EmailIds })
.GroupBy(x => x.EmailIds)
.Select(x => new
{
ID = x.Key,
Values = String.Join(",", x.Select(z => z.trackObj.ID))
}).OrderBy(x => x.ID);
Working Fiddle.
I have 2 tables:
Schools
-------
pk_school_id,
title
and
Business_Hours
--------------
pk_id,
fk_school_id
I want pk_school_id and title from School Table for all pk_school_id that does not exist as fk_school_id in Business_Hours table.
var Schools = (from b in Db.Language_School_Business_Hours
join s in Db.Language_Schools on b.fk_school_id equals s.pk_school_id into lrs
from lr in lrs.DefaultIfEmpty()
select new
{
LeftID = b.fk_school_id,
RightId = ((b.fk_school_id == lr.pk_school_id) ? lr.pk_school_id : 0)
});
try this to achieve your goal, without join, just take elements that are not contained in Business_Hours table
var Schools = Db.Language_Schools
.Where(s => !Db.Language_School_Business_Hours
.Select(b => b.fk_school_id).ToList().Contains(s.pk_school_id))
.Select(x => new
{
x.pk_school_id,
x.school_title
});
I think we can a bit simplify the linq by removing .ToList() after the first .Select(...), removing the last .Select(...). Pls take a look at a below code.
var schools = Db.Language_Schools
.Where(w => !Db.Language_School_Business_Hours
.Select(s => s.fk_school_id)
.Contains(w.pk_school_id))
.ToList();