LINQ join with top 1 from another table - c#

So the scenario is I have a table of items, and for each item there is a number of comments in another table. I want to get a list of the items with the LATEST comment.
I did this:
var res = (from i in db.Item
select new
{
ID = i.ID,
Name = i.Name,
Comment = (from c in db.Comment
orderby c.Created descending
where c.Item == i.ID
select new { Message = c.Message }).FirstOrDefault().Message
});
Ok, this gets me the results I want, but it's so SLOW... Please, help me make a join out of this instead!
Thank you!

Try this:
var res = db.Item.Join(db.Comment, x=>x.ID, x=>x.ID, (x,y)=>new{x,y})
.OrderByDescending(a=>a.y.Created)
.GroupBy(a=>a.x.ID,(key,items)=>items.First())
.Select(a=> new {
a.x.ID,
a.x.Name,
a.y.Message
});

Related

How to assign values to a list by linq without for or foreach statements?

I want to compare two lists and assign 1st list to another in case of requirement.
var getdetail=_readonlyservice.getdetail().ToList();
foreach(var item in docdetail)
{
var temp=getdetail.firstordefualt(i=>i.Id=item.Id)
if(temp==null) continue;
item.code=temp.code;
}
I want to implement top statements in linq .any help ?
Think so..
var getdetail=_readonlyservice.getdetail().ToList();
var tempList = from dd in context.docdetail
join g in context.getdetail on dd.Id equals g.Id
select new // Your type
{
// Columns...
Code = g.Code
}
I believe you are trying to do like the way I did, although I was going to join table.
var result = (from e in DSE.employees
join d in DSE.departments on e.department_id equals d.department_id
join ws in DSE.workingshifts on e.shift_id equals ws.shift_id
select new
{
FirstName = e.FirstName,
LastName = e.LastName,
Gender = e.Gender,
Salary = e.Salary,
Department_id = e.department_id,
Department_Name = d.department_name,
Shift_id = ws.shift_id,
Duration = ws.duration,
}).ToList();
// TODO utilize the above result
I was using DTO method to do this. And then you return result(as this case is result).
You may view the whole question and solution here.
As this case, you are not required to put foreach loop, as the query said from every row in yourdatabase.table

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

Linq to SQL, contains in where clause repeated values

I have a simple table of items, called "ITEMS":
id description
-- -----------
1 Something
2 Another thing
3 Best thing
I have a list of Int32 which are item IDs I'd like to show:
List<Int32> currentItemsCodes = new List<int>();
For this example currentItemsCodes contains 1,2,2,3
Currently I have this Linq-to-SQL:
var itemDescriptions = (from a in db.ITEMS
where currentItemsCodes.Contains(a.id)
select new {a.id, a.description});
What this returns is:
1,Something
2,Another thing
3,Best thing
I need to return two "Another things":
1,Something
2,Another thing
2,Another thing
3,Best thing
Or if currentItemsCodes was 3,3,3,3 I would need 4 x "Best thing" returned
You should do a inner join in linq to get what you are looking for. Use the below linq query to do that.
var itemDescriptions = (from a in db.ITEMS
join c in currentItemsCodes
on a.id equals c
select new {a.id, a.description});
You can use a join clause for that:
var itemDescriptions = (from item in db.ITEMS
join i in currentItemsCodes on item.id equals i
select new
{
id = item.id,
description = item.description
}).ToList();
Something like this?
var x = db.items;
var itemDescriptions = (from a in currentItemsCodes
select new {a, x[a].description});
As in Kris's comments substitute for [a] a method to access the items by id

LINQ: adding OrderBy to query

I'm at the finish line for my university project, and I'm kinda stuck at finishing a query.
The working query looks like this:
var Report = from query in Document.Descendants("order")
group query by query.Element("seller").Value
into qGroup
select new Orders
{
Seller = qGroup.Key,
Quantity = qGroup.Sum(p => int.Parse(p.Element("quantity").Value)).ToString()
};
I would really appreciate it if you can show me, how to Order the results by the given "Quantity" in descending order.
Thanks!
var Report = (from query in Document.Descendants("order")
group query by query.Element("seller").Value into qGroup
select new Orders
{
Seller = qGroup.Key,
Quantity = qGroup.Sum(p => int.Parse(p.Element("quantity").Value)).ToString()
})
.OrderByDescending(order => order.Quantity);
Please do this :
var Report = (from query in Document.Descendants("order")
group query by query.Element("seller").Value
into qGroup
select new Orders
{
Seller = qGroup.Key,
Quantity = qGroup.Sum(p => int.Parse(p.Element("quantity").Value)).ToString()
}).OrderByDescending(x => x.Quantity);
HTH !!!!
(Kudos to LINQ Orderby Descending Query )
The answers by Skippy and Andrei work, but you can also write as
var Report = from query in Document.Descendants("order")
group query by query.Element("seller").Value
into qGroup
let qty = qGroup.Sum(p =>int.Parse(p.Element("quantity").Value)).ToString()
orderby qty descending
select new Orders
{
Seller = qGroup.Key,
Quantity = qty
};
if you'd rather keep it all in one syntax.

LINQ to SQL omit field from results while still including it in the where clause

Basically I'm trying to do this in LINQ to SQL;
SELECT DISTINCT a,b,c FROM table WHERE z=35
I have tried this, (c# code)
(from record in db.table
select new table {
a = record.a,
b = record.b,
c = record.c
}).Where(record => record.z.Equals(35)).Distinct();
But when I remove column z from the table object in that fashion I get the following exception;
Binding error: Member 'table.z' not found in projection.
I can't return field z because it will render my distinct useless. Any help is appreciated, thanks.
Edit:
This is a more comprehensive example that includes the use of PredicateBuilder,
var clause = PredicateBuilder.False<User>();
clause = clause.Or(user => user.z.Equals(35));
foreach (int i in IntegerList) {
int tmp = i;
clause = clause.Or(user => user.a.Equals(tmp));
}
var results = (from u in db.Users
select new User {
a = user.a,
b = user.b,
c = user.c
}).Where(clause).Distinct();
Edit2:
Many thanks to everyone for the comments and answers, this is the solution I ended up with,
var clause = PredicateBuilder.False<User>();
clause = clause.Or(user => user.z.Equals(35));
foreach (int i in IntegerList) {
int tmp = i;
clause = clause.Or(user => user.a.Equals(tmp));
}
var results = (from u in db.Users
select u)
.Where(clause)
.Select(u => new User {
a = user.a,
b = user.b,
c = user.c
}).Distinct();
The ordering of the Where followed by the Select is vital.
problem is there because you where clause is outside linq query and you are applying the where clause on the new anonymous datatype thats y it causing error
Suggest you to change you query like
(from record in db.table
where record.z == 35
select new table {
a = record.a,
b = record.b,
c = record.c
}).Distinct();
Can't you just put the WHERE clause in the LINQ?
(from record in db.table
where record.z == 35
select new table {
a = record.a,
b = record.b,
c = record.c
}).Distinct();
Alternatively, if you absolutely had to have it the way you wrote it, use .Select
.Select(r => new { a = r.a, b=r.b, c=r.c }).Distinct();
As shown here LINQ Select Distinct with Anonymous Types, this method will work since it compares all public properties of anonymous types.
Hopefully this helps, unfortunately I have not much experience with LINQ so my answer is limited in expertise.

Categories

Resources