I have List collection of Message objects.
public class Message
{
public int Id { get; set; }
public string Body { get; set; }
public string Sender { get; set; }
public DateTime Timestamp { get; set; }
}
I want to get only one message with most recent Timestamp for each sender. How do I do it using LINQ?
You need to group by Sender and then get the Max Timestamp from each group like:
var query = list.GroupBy(r => r.Sender)
.Select(grp => new
{
Sender = grp.Key,
RecentTimeStamp = grp.Max(r => r.Timestamp)
});
Or you can sort the TimeStamp in group by descending order and get the first element like:
var query = list.GroupBy(r => r.Sender)
.Select(grp => new
{
Sender = grp.Key,
RecentTimeStamp = grp.OrderByDescending(r => r.Timestamp).FirstOrDefault()
});
var q = from n in table
group n by n.Senderinto g
select g.OrderByDescending(t=>t.Timestamp).FirstOrDefault();
Related
I need to convert an IEnumerable to something else to be able to use Sum. What can I do to achieve this?
CsTotCommit = h.Sum(x => x.CSTotCommit)
I receive an error stating that:
CapStackTrancheDTO does not contain a definition for 'Sum' accepting a first argument of type CapStackTrancheDTO.
IEnumerable<CapStackTrancheDTO> debtRank = debt.AsEnumerable()
.Select((g,index) =>
new CapStackTrancheDTO
{
Rankid = index + 1,
CsTrancheId = g.CsTrancheId,
CsId = g.CsId,
CsTotCommit = g.CsTotCommit,
});
IEnumerable<CapStackTrancheDTO> debtSum = debtRank
.Select(h =>
new
{
CsId = h.CsId,
CsTotCommit = h.Sum(x => x.CSTotCommit)
});
Here are the class defintions:
public class CapStackTrancheDTO
{
public int? Rankid { get; set; }
public int? CsTrancheId { get; set; }
public int? CsId { get; set; }
public decimal? CsTotCommit { get; set; }
}
There are multiple records which I want to group by CsId and SUM.
From the comments, you've said that you want to group by CsId and then sum.
Currently, you're not applying any grouping.
Use the .GroupBy method, like this:
IEnumerable<CapStackTrancheDTO> debtSum = debtRank
.GroupBy(h => h.CsId)
.Select(h =>
new CapStackTrancheDTO
{
CsId = h.Key, // the value we grouped on above is now available in `Key`
CsTotCommit = h.Sum(x => x.CSTotCommit)
}
);
I have a List of :
public class GT
{
public string ActivityName { get; set; }
public int Seconds { get; set; }
}
And the ActivityName could repeat through the iteration and what I want to do is, regroup all the items that have the same name and calculate the average of seconds of these specifics items. I tried to use Distinct but it didn't group them.
You should use GroupBy instead of Distinct:
List<GT> list = /*...*/;
var query = list.GroupBy(x => x.ActivityName, (k,g) => new { ActivityName = k, AverageTimeInSeconds = g.Average(x => x.Seconds) });
var groups = items.GroupBy(p => p.ActivityName)
.Select(g => new
{
ActivityName = g.Key,
Average = g.Average(t => t.Seconds)
}).ToList();
I'm stuck on a Linq-to-SQL query. I have a table of items, with multiple items per user. I want to get the list of all the latest items per user. This is what I have:
var TheList = (from t in MyDataContext.TheTable
where t.SomeDate > DateTime.UtcNow.AddMonths(-3)
group t by t.UserID into TheUserGroups
from g in TheGroups
orderby g.SomeDate descending
select new SomeObject()
{
TheUserID = g.UserID,
.....
}).ToList();
The problem is that it's returning all the items of every user instead of the most recent element per user. What do I need to change to get the expected result?
Try following :
var TheList = (from t in MyDataContext.TheTable
where t.SomeDate > DateTime.UtcNow.AddMonths(-3)
orderby g.SomeDate descending
select new SomeObject()
{
TheUserID = g.UserID,
})
.GroupBy(x => x.TheUserID)
.Select(x => x.FirstOrDefault())
.ToList();
If I understood you correctly:
public class Order
{
public int OrderId { get; set; }
public int UserId { get; set; }
public DateTime Date { get; set; }
public string ItemName { get; set; }
}
table.Where(o => o.Date < DateTime.UtcNow.AddMonths(-3))
.GroupBy(o => o.UserId)
.Select(g => new { UserId = g.Key, LastOrder = g.OrderByDescending(o => o.Date).FirstOrDefault() })
.ToList();
I need to group a list of questions by speaker using Linq:
public partial class Question
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime Date { get; set; }
public string Description { get; set; }
[ForeignKey("Speaker")]
public int Speaker_Id { get; set; }
public virtual Speaker Speaker { get; set; }
}
public partial class Speaker
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public string Title { get; set; }
}
I need to create a list of Questions Grouped By Speaker:
Question.Date | Speaker.Name | Question.Description
I get here but it's not working:
db.Questions.Select(c => new
{
c.Date,
c.Description,
c.Speaker.Id
})
.ToList()
.GroupBy(c => new { c.Id, c.Date, c.Description })
.Select(g => new Question
{
Date = g.Key.Date,
Speaker = db.Spkeakers.Where(o => o.Id == g.Key.Id).FirstOrDefault(),
Description = g.Key.Description
})
.ToList());
It's sorting by Date and not grouping by Speaker.
You're including Date (a DateTime type) in your group by clause. There's a good chance that each of your rows has a different date. If that property is true for your data, then grouping by date is essentially grouping by a unique identifier. Instead, maybe try to group by a less granular date by grouping by day, month, year, etc. Also, you could just group by speakerId and only order by date.
To order by speaker and date do this:
var result = db.Questions
.OrderBy(t => t.Speaker_Id)
.ThenBy(t => t.Date);
This is how you group by speakers and give a count:
var result = db.Questions
.GroupBy(t => t.Speaker_Id)
.Select(g => new { Speaker_Id = g.Key, count = g.Count() });
This is how you show this table ordered by date
var result = db.Questions
.OrderBy(t => t.Date)
.Select(item => new { Date = item.Date, Name = item.Speaker.Name, D = item.Description });
Note, if you want a list of Questions as your result then the last select is not needed.
I have two classes:
class Customer
{
public string Name { get; set; }
public string ZipCode { get; set; }
public List<Order> OrderList { get; set; }
}
class Order
{
public string OrderNumber { get; set; }
}
Using LINQ, i want to get list of Orders group by ZipCode. If Zipcode "12121" has 10 customers and each has 2 orders then it should return me only one Zipcode with the list of 20 orders.
I am trying to do it like this but not able to figure out whats wrong
var orders = br.CustOrderList
.Select(r => new
{
r.ZipCode,
r.Name,
r.OrderList
})
.GroupBy(x => new { x.ZipCode, x.OrderList});
Any help please?
This should do what you want:
var orders = br.CustOrderList
.GroupBy(x => x.ZipCode)
.Select(g => new
{
ZipCode = g.Key,
Orders = g.SelectMany(x => x.OrderList)
});
var orders = br.CustOrderList
.Select(r => new
{
r.ZipCode,
r.Name,
r.OrderList
})
.GroupBy(x => x.ZipCode);
You just want to group by the ZipCode so just group by that
Ah yea just try
var order = br.CustOrderList
.GroupBy(x = x.ZipCode);
No need to select new items out of the list