LINQ syntax help: projection and grouping - c#

New to LINQ.. I am curious as to the syntax to do the following SQL query in LINQ
SELECT MAX(TMPS), DAY FROM WEATHERREADINGS
GROUP BY WEATHERREADINGS.DAY
What I have so far:
var minTemps = from ps in ww.WEATHERREADINGS
group ps by ps.DATE.Hour into psByHour
select new
{
HourOfDay = psByHour.Max().DATE.Hour,
MaxTemp = psByHour.Max().TMPS
};
I am getting the following error while doing this:
Exception Details: System.InvalidOperationException: Could not format node 'New' for execution as SQL.
any help greatly appreciated!!

I think the following is what you want. Note that you can get the key from the grouping so there is no need to aggregate there. You need to provide a mechanism to select the item to do the aggregation on for the other.
var maxTemps = from ps in ww.WEATHERREADINGS
group ps by ps.Date.Hour into psByHour
select new
{
HourOfDay = psByHour.Key,
MaxTemp = psByHour.Max( p => p.TMPS )
};

Or the functional approach that i tend to like better:
var result = ww.WEATHERREADINGS
.GroupBy(a => a.Date.Hour)
.Select(a => new
{
Hour = a.Key,
Max = a.Max(b => b.TMPS)
});

Related

How can get values using LINQ from multilevel variable

I want to unable to fetch values using LINQ. I am using below code for fetching data.
SearchParameters sp3 = new SearchParameters()
{
Filter = "name eq 'test'",
Top = 5,
QueryType = QueryType.Full,
Select= new List<string>() { "Query" },
};
if (highlights)
{
sp3.HighlightPreTag = "<b>";
sp3.HighlightPostTag = "</b>";
}
DocumentSearchResult suggestResult = _indexClient1.Documents.Search(term,sp3);
List<string> suggestions = (from p in suggestResult
.Results.Select(s => s.Document)
.Select(y => y.Values.ToString())
select p).ToList();
Hierarchy is Document->Result->Query.
I am getting values till Result level but I want to get data till Query Level.
I am not expert in LINQ.
screenshot
output
I think what you are looking for is something like this:
suggestResult.Results.SelectMany(s => s.Document.Select(d => d.Query)).ToList()
It should give you a list of all Query-Objects over all Document Results.
If you want the Query as string you have to get another property of Query in the inner Select or call ToString() on it.

Join 2 table and group 2 field in linq

I have a very simple SQL
SELECT s.shop_code
,SUM(im.amt) sum_amt
,s.cell_no#1 shop_cell
FROM tb_sn_so_wt_mst im
,tb_cm_shop_inf s
WHERE im.shop_code = s.shop_code
GROUP BY s.shop_code, s.cell_no#1)
then i try to code linq
var listResult = from warrantyMaster in listWarrantyMasters2.Records
join shopInfo in listShopInfos
on warrantyMaster.ShopCode equals shopInfo.ShopCode
i don't know group by shop code and cell no and sum atm, any one help me out of this problem
The group by syntax with some examples is explained here group clause (C# Reference) and related links.
Here is the direct translation of your SQL query (of course the field names are just my guess since you didn't provide your classes):
var query = from im in listWarrantyMasters2.Records
join s in listShopInfos
on im.ShopCode equals s.ShopCode
group im by new { s.ShopCode, s.CellNo } into g
select new
{
g.Key.ShopCode,
g.Key.CellNo,
SumAmt = g.Sum(e => e.Amt)
};
You can try this code:
var results = from warrantyMaster in listWarrantyMasters2.Records
from shopInfo in listShopInfos
.Where(mapping => mapping.ShopCode == warrantyMaster.ShopCode )
.select new
{
ShopCode = warrantyMaster.ShopCode,
ATM = listWarrantyMasters2.ATM,
ShellNo = shopInfo.ShellNo
}
.GroupBy(x=> new { x.ShopCode, x.ShellNo })
.Select(x=>
new{
ShopCode = x.Key.ShopCode,
ShellNo = x.Key.ShellNo,
SumATM = x.Sum(item=>item.ATM)
});

What are the two ways I can write this statement with LINQ?

I understand that there are two different ways I can write LINQ code. Can someone show me the two ways for this simple code block. Which is the most commonly used or considered most easy to debug
var subTopics = _subTopicService.GetSubTopics(Id);
var subTopicsSelect = (from subTopic in subTopics
select new
{
id = subTopic.SubTopicId,
name = subTopic.Name
});
Since your query consists solely of a from and select clause, all you need to do to convert this to fluent syntax is call .Select.
In fluent syntax, that would be:
var subTopicsSelect = subTopics.Select(x =>
new
{
id = x.SubTopicId,
name = x.Name
});
Further Reading
How to: Write LINQ Queries in C#
You have displayed the first way "SQL-like syntax" the second would be "Lambda syntax":
subTopics.Select(s => new { id = s.SubTopicId, name = s.Name });
This really confuses me as I have a completely different way to select here are the two methods:
var emailsToSend = db.emailQueues.Where(
e => e.sent == false
).Take(5);
var emailsToSend2 = from e2 in db.emailQueues
.Take(5)
.Where(
e => e.sent == false
)
select e2;
They both seem to do exactly the same thing but i prefer the syntax of the first method. Its easier to remember.

C# LINQ Query

I have some data in a List of User defined types that contains the following data:
name, study, group, result, date. Now I want to obtain the name, study and group and then a calculation based onthe result and date. The calculation is effectively:
log(result).where max(date) minus log(result).where min(date)
There are only two dates for each name/study/group, so the result from the maximum data (log) minus the result from the minumum date (log). here is what I have tried so far with no luck:
var result =
from results in sortedData.AsEnumerable()
group results by results.animal
into grp
select new
{
animal = results.animal,
study = results.study,
groupNumber = results.groupNumber,
TGI = System.Math.Log(grp.Select(c => c.volume)
.Where(grp.Max(c=>c.operationDate)))
- System.Math.Log(grp.Select(c => c.volume)
.Where(grp.Min(c => c.operationDate)))
};
Anybody any pointers? Thanks.
It isn't entirely clear how the grouping relates to your problem (what sense does it make to extract a property from a range variable after it has been grouped?), but the part you're having difficult with can be solved easily with MaxBy and MinBy operators, such as the ones that come with morelinq.
var result = from results in sortedData.AsEnumerable()
group results by results.animal into grp
select new
{
animal = grp.Key,
study = ??,
groupNumber = ??,
TGI = Math.Log(grp.MaxBy(c => c.operationDate).volume)
- Math.Log(grp.MinBy(c => c.operationDate).volume)
};
Otherwise, you can simulate these operators with Aggregate, or if you don't mind the inefficiency of sorting:
var result = from results in sortedData.AsEnumerable()
group results by results.animal into grp
let sortedGrp = grp.OrderBy(c => c.operationDate)
.ToList()
select new
{
animal = grp.Key,
study = ??,
groupNumber = ??,
TGI = sortedGrp.Last().volume - sortedGrp.First().volume
};
You have a few syntax problems, you cannot use the results parameter after your into grp line. So my initial attempt would be to change your statement like so
var result =
from results in sortedData.AsEnumerable()
group results by new
{
Animal = results.animal,
Study = results.study,
GroupNumber = results.groupNumber
}
into grp
select new
{
animal = grp.Key.Animal,
study = grp.Key.Study,
groupNumber = grp.Key.GroupNumber,
TGI = System.Math.Log(grp.OrderByDescending(c=>c.operationDate).First().volume)
- System.Math.Log(grp.OrderBy(c=>c.operationDate).First().volume)
};

LINQ group by not working

I've read lots of group by replies in this forum, but I have to ask anyway:
var errandQuery = (from t in db.TimereportSet
group t by new { t.Errand.Name, t.Date } into g
select new ErrandTime { Date = g.Key.Date, Value = g.Sum(e => e.Hours) }).ToList();
why isn't this working. I get the following exception: "Unknown column 'GroupBy1.K1' in 'field list'"
the exception comes from the mySQLClient.
You're not selecting Hours into g, so they aren't there to sum.
I don't know what your data looks like but try this:
EDIT:
var errandQuery = (from t in db.TimereportSet
group t by new { t.Errand.Name, t.Date } into g
select new ErrandTime { Date = g.Key.Date, Value = g.Sum**(t => t.Hours)** }).ToList();
Sorry, my first response was incorrect.
You LINQ query is correct, except right at the end --- you are using e.. where you need to reference the items you selected ... so you would need to use t in your lambda expression instead of e
I wrote this as a comment but it should be an answer, this is a confirmed bug in mySQL with LinQ. Is there another way of querying for the same thing using a work around, objectquery or direct sql or something else using the entity framework:
var errandQuery = (from t in db.TimereportSet
group t by new { t.Errand.Name, t.Date } into g
select new ErrandTime {
Date = g.Key.Date,
Value = g.Sum(e => e.Hours)}).ToList();
or should I create a new post for this question?

Categories

Resources