How can i use unioan and nested from linq? - c#

How can i convert to sql to linq . i don't understand nested select query. i need linq codes. Please help me:((((
SELECT #id=id FROM
(SELECT id,workorder AS workorderno ,CAST(jobseqno AS int) AS jobseqno FROM dbo.CTask
UNION ALL
SELECT id,workorderno,cardno AS jobseqno FROM dbo.NonRoutineCard
UNION ALL
SELECT id,workorderno,cardno AS jobseqno FROM dbo.AdditionalWorkCard) a
WHERE RTRIM(workorderno)=RTRIM(#ToNo) AND jobseqno=#ToSeq
LINQ:
var id =
(from task in stock.CTasks select new { task.id, task.workorder, task.jobseqno } )
.Union(from card in stock.NonRoutineCards select new { card.id, card.workorderno, card.cardno })
.Union(from card in stock.AdditionalWorkCards select new { card.id, card.workorderno, card.cardno })
.Where(x => x.workorderno.TrimEnd() == ToNo && x.jobseqno == ToSeq)
.FirstOrDefault();
if i write above codes error below:

will that suit your needs?
var id =
(from task in stock.CTasks select new { task.id, task.workorder, jobseqno= task.jobseqno } )
.Union(from card in stock.NonRoutineCards select new { card.id, card.workorderno, jobseqno = card.cardno })
.Union(from card in stock.AdditionalWorkCards select new { card.id, card.workorderno, jobseqno = card.cardno })
.Where(x => x.workorderno.TrimEnd() == ToNo && x.jobseqno == ToSeq)
.FirstOrDefault();

Related

How to Convert SQL query to LINQ (to get last record each bookingStatus)

Need some help translating below query to LINQ.
;With BookingWithLastStatus
as
(
Select *, Rnk = ROW_NUMBER() over (partition by BookingId order by Id desc)
from BookingStatus
)
Select *
from BookingWithLastStatus
where Rnk=1 AND StatusId = 3
I've done LINQ below but it is not getting the correct records.
var BookStatus = from p in _context.Set<BookingStatus>()
where p.StatusId == 3
group p by p.BookingId into opt
select new {
BookingId = opt.Key,
Id = opt.Max(x => x.Id)
};
The SQL query is getting 1 record only which is correct and my LINQ is getting multiple records.
UPDATE:
I did like this:
Get all the BookingStatus first
var GetAllBookStatus = await _context.Set<BookingStatus>()
.ToListAsync();
Then do the filtering based from the SQL Query I need.
var FilteredBookStatus = GetAllBookStatus
.OrderByDescending( x => x.Id )
.GroupBy(person => person.BookingId)
.Select( group => new { Group = group, Count = group.Count() } )
.SelectMany( groupWithCount =>
groupWithCount.Group.Select( b => b)
.Zip(
Enumerable.Range( 1, groupWithCount.Count ),
( b, i ) => new {
b.Id,
b.BookingId,
b.BookingMWABId,
b.BookStatus,
b.CreatedBy,
b.CreatedDate,
b.Destination,
b.InternalStatus,
b.LineNum,
b.ModifiedBy,
b.ModifiedDate,
b.Module,
b.ReasonCode,
b.ReceivedBy,
b.RefNo,
b.StatusId,
b.TimeStamp,
RowNumber = i }
)
)
.Where(a => a.StatusId == 3 && a.RowNumber == 1)
.ToList();
But I'm not so confident on Getting all records, as it will grow some time. Is there anything I can change from my code?
With EF core 6.x, you can do the following. It is not optimal case as in your SQL, but should work:
var BookStatus =
from p in _context.Set<BookingStatus>()
group p by p.BookingId into g
select g.OrderByDescending(x => x.Id).First();
BookStatus = BookStatus.Where(p => p.StatusId == 3);
Or another variant
var BookStatus = _context.Set<BookingStatus>().AsQueryable();
BookStatus =
from d in BookStatus.Select(d => new { d.BookingId }).Distinct()
from p in BookStatus
.Where(p => p.BookingId == d.BookingId)
.OrderByDescending(p => p.Id)
.Take(1)
select p;
BookStatus = BookStatus.Where(p => p.StatusId == 3);

Yet another “A query body must end with a select clause or a group clause”

This query does work, but I am trying to combine the two steps into one query.
var query1 = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>()
.Where
(u =>
u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office)
)
select new
{
hOffice = o.Name,
bName = u.Name
};
var query2 = query1.GroupBy(t => new { office = t.hOffice, name = t.bName })
.Select(g => new { Office = g.Key.office, Name = g.Key.name, Count = g.Count() });
If I try to combine the two queries using the following query it gives me the “A query body must end with a select clause or a group clause” error.
var query1 = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>()
.Where
(u =>
u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office)
)
.GroupBy(t => new { office = t.Office, name = t.Name })
.Select(g => new { Office = g.Key.office, Name = g.Key.name, Count = g.Count() });
I think I have to add a select something, but I can't figure out what.
Can anyone please help?
Your query must contain a select clause. The .Where(...).GroupBy(...).Select(...) are only on the db.GetTable<Users>(). Something like:
var query1 = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>().Where(u => u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office))
.GroupBy(t => new { office = t.Office, name = t.Name })
.Select(g => new { Office = g.Key.office, Name = g.Key.name, Count = g.Count() })
select new { /* Desired properties */};
But I think you are looking for something like:
var result = from b in db.GetTable<Boats>()
from o in db.GetTable<Offices>()
from u in db.GetTable<Users>()
where u.UserId == b.Handling_broker &&
o.Office == b.Handling_office &&
b.Status == 2 &&
officesToInclude.Contains(b.Handling_office))
group 1 by new { t.Office, t.Name } into g
select new { Office = g.Key.Office, Name = g.Key.Name, Count = g.Count() };

Convert SUM / CASE WHEN / GROUP BY SQL query into LINQ

I am having a VERY hard time converting my simple SQL query to LINQ...
SELECT Id
,Location
,SUM( CASE
WHEN TransactionType = 'Out' THEN [Quantity] * -1
ELSE Quantity
END) AS StockQuantity
FROM Transactions
WHERE Id = 123
GROUP BY Id, Location
here is my best WRONG attempt...
var result = db.Transactions
.Where(r => r.Id == 123)
.GroupBy(r => r.Id, r => r.Location)
.Select(group => new
{
Id = r.Id,
Location = r.Location,
Quantity = sum(r.TransactionType == 2 ? r.Quantity * -1 : r.Quantity),
});
Thanks in advance
You are not using your grouped values. Your query should be like:
var result = db.Transactions
.Where(r => r.Id == 123)
.GroupBy(r => new { r.Id, r.Location} )
.Select(grp => new
{
Id = grp.Key.Id,
Location = grp.Key.Location,
Quantity = grp.Sum(t=> t.TransactionType == 2 ? t.Quantity * -1 : t.Quantity),
});
I would also use a different variable name than group in projection (Select) since it is a contextual keywords (with query expression)

what am i doing wrong in constructing Linq query

I am trying to write equivalent linq code for following query.
SELECT A.*
FROM
(
SELECT * FROM TableA
WHERE id = 100
) a
JOIN
(
SELECT Name, MAX(AnotherId) AnotherId
FROM TableA
WHERE id = 100
GROUP BY Name
) b
on a.Name = b.Name and a.AnotherId = b.AnotherId
This is the linq
var Collection = from R in DbContext.TableA
join G in (DbContext.TableA.Where(r => r.Id == 100).GroupBy(r => new { r.Name, r.AnotherId } ).Select(g => new { Name = g.Name , AnotherId = g.Max(o => o.AnotherId) }))
on new { R.Name, R.AnotherId } equals new { G.Name, G.AnotherId }
where R.Id == 100
select R;
But I am getting following compilation error that I don’t know how to fix. Any thoughts
The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.
Error 7 'System.Linq.IGrouping' does not contain a definition for 'Name' and no extension method 'Name' accepting a first argument of type 'System.Linq.IGrouping' could be found (are you missing a using directive or an assembly reference?)
You group by r.Name, r.AnotherId, when you just want to group by r.Name.
var Collection = from R in DbContext.TableA
join G in (DbContext.TableA
.Where(r => r.Id == 100)
.GroupBy(r => r.Name)
.Select(g => new { Name = g.Key , AnotherId = g.Max(o => o.AnotherId) }))
on new { R.Name, R.AnotherId } equals new { G.Name, G.AnotherId }
where R.Id == 100
select R;
And to have all in Fluent Syntax
var collection = DbContext.TableA
.Where(t1 => t1.Id == 100)
.Join(DbContext.TableA
.Where(t2 => t2.Id == 100)
.GroupBy(t2 => t2.Name)
.Select(group => new{Name = group.Key,
AnotherId = group.Max(e => e.AnotherId)})
),
t1 => new{t1.Name, t1.AnotherId} ,
t2 => new{t2.Name, t2.AnotherId},
(t1, t2) => t1);
llHi you need the following syntax, notice the addition of 'Key'
var Collection = from R in DbContext.TableA
join G in (DbContext.TableA.Where(r => r.Id == 100)
.GroupBy(r => new { r.Name, r.AnotherId } )
.Select(g => new { Name = g.Key.Name , AnotherId = g.Max(o => o.AnotherId) }))
on new { R.Name, R.AnotherId } equals new { G.Name, G.AnotherId }
where R.Id == 100
select R;
I would recommend using the query syntax for all parts of your query. By doing it this way, your linq query will have a more similar structure to your original sql query. It would look like this:
var query =
from a in
(from x in DbContext.TableA
where x.ID == 100
select x)
join b in
(from x in DbContext.TableA
where x.ID == 100
group x by x.Name into x
select new
{
Name = x.Key,
AnotherId = x.Max(o => o.AnotherId),
})
on new { a.Name, a.AnotherId } equals new { b.Name, b.AnotherId }
select a;
saj and Raphael both have found good points:
.GroupBy(r => new { r.Name, r.AnotherId } )
.Select(g => new { Name = g.Name , AnotherId = g.Max(o => o.AnotherId) }))
Groups don't have a Name. Each group has a Key (and the Key has a Name and AnotherId).
Since you want the Max(AnotherId), you don't want to include AnotherId in your grouping Key (same as it is not present in the GroupBy clause of the original query).
.GroupBy(r => r.Name) //the Name is the Key
.Select(g => new { Name = g.Key, AnotherId = g.Max(o => o.AnotherId) }))

Unknown column error using Entity Framework and LINQ

I started with EF yesterday and I am in trouble to transform this simple query into EF sintax
Translate:
select a.city from offer o, address a, offer_address oa
where o.identifier = oa.offeridentifier
and a.identifier = oa.addressidentifier
group by a.city
order by count(*) desc
Into:
var cities = (from o in db.offer
from a in db.address
from oa in db.offer_address
where (o.identifier == oa.offeridentifier
&& a.identifier == oa.addressidentifier)
group a by a.city into c
select new
{
quantity = c.Count(),
city = c.Key
}).OrderByDescending(a => a.quantity).Select(a => a.city);
var cityCollection = new List<string>();
foreach (var city in cities)
cityCollection.Add(city.ToString());
I have tried withou success
var cities = (from oa in db.offer_address
from of in db.offer.Where(x => x.identifier == oa.identifier)
from ad in db.address.Where(y => y.identifier == oa.offeridentifier).AsEnumerable()
group ad.city by new { ad.city } into g
select new
{
quantity = g.Count(),
city = g.Key
}).OrderByDescending(a => a.quantity);
The problem occurs when try to get inside the first loop!
Unknown column 'GroupBy1.K1' in 'field list'`
Line 55: foreach (var city in cities)`
With the second case:
Can't group on 'A1'
UPDATE
This code works, but its not i need
var cities = (
from of in db.offer
from ad in db.address
from oa in db.offer_address
where (of.identifier == oa.offeridentifier && ad.identifier == oa.addressidentifier)
group ad.city by new { ad.city } into g
select new
{
quantity = g.Count()
}).OrderByDescending(a => a.quantity)
Or
var cities = (
from of in db.offer
from ad in db.address
from oa in db.offer_address
where (of.identifier == oa.offeridentifier && ad.identifier == oa.addressidentifier)
group ad.city by new { ad.city } into g
select new
{
city = g.Key
});
Update - Try adding AsEnumerable() after the first select
var query = (from o in db.offer
from a in db.address
from oa in db.offer_address
where (o.identifier == oa.offeridentifier && a.identifier == oa.addressidentifier)
group a by a.city into c
select new
{
quantity = c.Count(),
city = c.Key
})
.AsEnumerable()
.OrderByDescending(a => a.quantity)
.Select(a => a.city);

Categories