Linq to entities query with nested query on the same table - c#

I have a SQL query:
SELECT distinct A.stock_value_site,
A.BALANCE_QUANTITY,
A.BALANCE_NOMINAL_VALUE,
A.BALANCE_INDEXED_VALUE,
V.STOCK_VALUE_ORDER,
U.BALANCE_QUANTITY
FROM svr A,
svt V,
svu U
WHERE V.Code = 500 and
A.Id = U.ID (+) and
A.Id = (SELECT max(B.id)
FROM svr B,
sts
WHERE A.stock_value_site = B.stock_value_site and
B.Id = sts.ID(+) and
B.item = _item and
B.date < _from_date and
B.Id IS NULL)
I tried to convert this query to Linq to entities:
var data = (from A in _context.svr
join V in _context.svt on A.svtId equals V.Code
join U in _context.svu on A.Id equals U.Id into groupA
from gA in groupA.DefaultIfEmpty()
where V.Code == _openBalanceRecordId &&
A.Id == (from B in _context.svr
join st in _context.sts on B.Id equals st.Id into groupB
from gB in groupB.DefaultIfEmpty()
where A.svsId == B.svsId &&
B.ItemId == _item &&
B.Date < _startDate.Date
select B.Id).Max()
select new
{
A.stock_value_site,
A.BALANCE_QUANTITY,
A.BALANCE_NOMINAL_VALUE,
A.BALANCE_INDEXED_VALUE,
V.STOCK_VALUE_ORDER,
gA == null ? 0 : gA.BALANCE_QUANTITY
}).Distinct().ToList();
When I run the SQL query in oracle I get 33 records back. But when I run it using Linq to entities I don't get any record.
What am I doing wrong?

I believe there are still some issues with you're original query, if I understand what you're trying to do, this should work better:
var results =
(from a in _context.svr
from v in _context.svt.Where(t => t.Code == 500)
join u in _context.svu on u.Id equals a.Id into gU
from x in gU.DefaultIfEmpty()
where a.Id ==
(from b in _context.svr
join s in _context.sts on b.Id equals s.Id
where b.item = _item
and b.date < _from_date
and b.svsId == a.svsId
select b.Id).Max()
select new
{
a.stock_value_site,
a.BALANCE_QUANTITY,
a.BALANCE_NOMINAL_VALUE,
a.BALANCE_INDEXED_VALUE,
v.STOCK_VALUE_ORDER,
x == null ? 0 : x.BALANCE_QUANTITY
}).Distinct().ToList();
Or possibly this:
var results =
(from a in _context.svr
from v in _context.svt.Where(t => t.Code == 500)
join u in _context.svu on u.Id equals a.Id into gU
from x in gU.DefaultIfEmpty()
let subQuery =
(from b in _context.svr
join s in _context.sts on b.Id equals s.Id
where b.item = _item
and b.date < _from_date
select new { b.Id, b.svsId })
join y in subQuery on a.svsId equals y.svsId into gY
where a.Id = y.Max(b => b.Id)
select new
{
a.stock_value_site,
a.BALANCE_QUANTITY,
a.BALANCE_NOMINAL_VALUE,
a.BALANCE_INDEXED_VALUE,
v.STOCK_VALUE_ORDER,
x == null ? 0 : x.BALANCE_QUANTITY
}).Distinct().ToList();

Related

need to convert sql join query with count into linq and pass it to view

select COUNT([User].UserId)
from [User] join Team on [User].TeamId = Team.TeamId where Team.TeamId =2
Here's what I have so far, but I can't figure out how to implement
var countUser = from u in db.Users
join t in db.Teams
on u.TeamId equals t.TeamId
where (u.TeamId == 11)
select new
{
};
try this
var countUser = (from u in db.Users
join t in db.Teams
on u.TeamId equals t.TeamId
where (u.TeamId == 11)
select new
{
u.UserId
}).Count();

Linq outer join with where, need help to select first

I have a outer join with a where clause. It returns multiple responses and I need to select the first one.
from p in context.Persons
join c in context.Companies on p.PersonId equals c.CompanyId
join a1 in context.Addresses on p.AddressDeliveryId equals a1.AddressId into da from x1 in da.DefaultIfEmpty()
join a2 in context.Addresses on p.AddressInvoiceId equals a2.AddressId into ia from x2 in ia.DefaultIfEmpty()
//This line returns multiple answers
join a3 in context.Addresses on p.PersonId equals a3.PersonId into pa from x3 in pa.Where(a3 => a3.AddressLocationId == 5).DefaultIfEmpty()
orderby p.PersonId descending
where p.IsProvider.Equals(false)
&& p.Obsolete.Equals(false)
&& p.Locked.Equals(false)
&& p.IsCustomer.Equals(true)
&& p.PersonType.Equals(1)
select new
{
p, c, x1, x2, x3
};
So I need the x3 to only return the first row. Please help
This worked for me.
from p in context.Persons
join c in context.Companies on p.PersonId equals c.CompanyId
join a1 in context.Addresses on p.AddressDeliveryId equals a1.AddressId into da
from x1 in da.DefaultIfEmpty()
join a2 in context.Addresses on p.AddressInvoiceId equals a2.AddressId into ia
from x2 in ia.DefaultIfEmpty()
let a3 = context.Addresses.FirstOrDefault(a3 => a3.AddressLocationId == 5 && a3.PersonId == p.PersonId && a3.Obsolete == false)
//This line worked for me
orderby p.PersonId descending
where p.IsProvider.Equals(false)
&& p.Obsolete.Equals(false)
&& p.Locked.Equals(false)
&& p.IsCustomer.Equals(true)
&& p.PersonType.Equals(1)
select new
{
p,
c,
DeliveryAddress = x1.Address1,
DeliveryAddressCity = x1.PoCity,
DeliveryAddressZipCode = x1.PoPostalCode,
InvoiceAddress = x2.Address1,
InvoiceAddressCity = x2.PoCity,
InvoiceAddressZipCode = x2.PoPostalCode,
PhoneNumber = a3.Address1,
PhoneNumberAddressId = (a3 != null) ? a3.AddressId : -1,
};
I think you can just change the .DefaultIfEmpty() to .FirstOrDefault()
join a3 in context.Addresses on p.PersonId equals a3.PersonId into pa from x3 in pa.Where(a3 => a3.AddressLocationId == 5).FirstOrDefault()
This should only return you the first x3 element

Convert SqlServer Query to LINQ

I have written the below given query in SQL server 2008:
(SELECT p.postid,
p.title,
p.disabled,
l.locationname
FROM posts p
INNER JOIN categories c
ON p.categoryid = c.categoryid
INNER JOIN users u
ON p.userid = u.userid
INNER JOIN tags t
ON p.tagid = t.tagid
INNER JOIN locations l
ON p.locationid = l.locationid
LEFT JOIN postimages pm
ON p.postid = pm.postid
WHERE p.categoryid = 1
GROUP BY p.postid,
p.title,
p.disabled,
l.locationname)
ORDER BY p.postid DESC
I want to write the above query in LINQ.
I tried a little and able to write the query below:
var objPosts = (from p in _dbcontext.Posts
join us in _dbcontext.Users on p.UserId equals us.UserId
join tag in _dbcontext.Tags on p.TagId equals tag.TagId
join cat in _dbcontext.Categories on p.CategoryId equals cat.CategoryId
join loc in _dbcontext.Locations on p.LocationId equals loc.LocationId
join img in _dbcontext.PostImages on p.PostId equals img.PostId into gj
from postimg in gj.DefaultIfEmpty()
where p.Disabled == false && p.CategoryId == userPost.CategoryId || p.UserId == userPost.UserId || p.TagId == userPost.TagId || p.LocationId == userPost.LocationId
orderby p.PostId descending
select new
{
PostId = p.PostId,
PostTitle = p.Title,
//ImageInfo = postimg.ImagePath,
//ThumbNailInfo = p.ThubNailInfo,
PostShortDescription = p.ShortDescription,
UserId = us.UserId,
UserName = us.Name,
TagId = tag.TagId,
TagTitle = tag.Title,
CategoryId = cat.CategoryId,
CategoryName = cat.CategoryName,
LocationId = loc.LocationId,
LocationName = loc.LocationName
});
I am unable to apply the group by logic in LINQ. Can anyone please convert my SQL to LINQ. Thanks
group new { p, l } by new
{
p.postid,
p.title,
p.disabled,
l.locationname
} into g
orderby g.Key.PostId descending
select new
{
g.key.postid,
g.key.title,
g.key.disabled,
g.key.locationname
}
The missing part in your query is that you are not selecting anything...
You got the joins ok, left outer join ok, predicates (where), ordering, but no projection, and no group by.
Below should get you started:
group p by p.PostId into pg
select new {Post=p, Location=loc};
This would return return a collection of new objects whose properties Post and Location.

How can i join two table in Linq and display the join to Data GridView?

I'm trying to join two tables and to display the Join result into GridView in WinForms, but something is going wrong...
it's not giving me Error message or something, Please help!!
my code :
var temp = teacherCmbBx.SelectedItem.ToString();
var temp2 = (from c in context.Teachers
where temp == c.FirstName
select c).ToList();
long num = temp2[0].ID;
var teacherGroup = (from t in context.Teachers
join g in context.Groups on t.ID equals g.TeacherID
where num == t.ID
select t);
teachergrpGridView.DataSource = teacherGroup;
string temp3 = (string)teachergrpGridView.Rows[rowNum].Cells[0].Value;
You are almost there. You are just missing .ToList()
var teacherGroup = (from t in context.Teachers
join g in context.Groups on t.ID equals g.TeacherID
where num == t.ID
select t).ToList();
teachergrpGridView.DataSource = teacherGroup;
var teacherGroup = from t in context.Teachers
join g in context.Groups on t.ID equals g.TeacherID
where num == t.ID
select new {
t.Id ,
g.Name,
t.xxxx
};

Convert special SQL query to Linq

do you know how write this SQL Query to linq ?
SELECT *
FROM
a
INNER JOIN b
ON a.FkSubmissionId = b.Id
RIGHT JOIN c
ON a.FkItemId = c.Id
WHERE
(b.FkUserId = '...' OR b.FkUserId is null)
and
(c.FkTenderId = 2)
I use Linquer and the best I have from the tool is that :
Linq :
from
items in _context.Items
from
si in _context.si
join s in _context.s
on new { fki = si.fki } equals new { fki = s.Id }
into
submissions_join
from
s in submissions_join.DefaultIfEmpty()
...
Result in SQL :
SELECT *
FROM
[Items] AS [t0]
CROSS JOIN [SubmissionsItems] AS [t1]
LEFT OUTER JOIN [Submissions] AS [t2]
ON [t1].[FkSubmissionId] = [t2].[Id]
WHERE
(([t2].[FkUserId] = #p0) OR (([t2].[FkUserId]) IS NULL))
AND
([t0].[FkTenderId] = #p1)
So the final result it not what I get from the query I need...
Thank you for your help !!!
Try this:
var part1 =
from x in a
join y in b on x.FkSubmissionId equals y.Id
where b.FkUserId = "..."
select new {x, y};
var part2 =
from c in z
where c.FkTenderId == 2
join xy in part1
on z.Id equals xy.x.FkItemId
into xys
from xy in xys.DefaultIfEmpty()
select new {xy.x, xy.y, z};
I would reorder your query so you can use a left join instead of a right join
var query = from c in context.C
from a in context.A.Where(x => c.Id == x.FkItemId)
.DefaultIfEmpty()
join b in context.B on a.FkSubmissionId equals b.id
where b.FkUserId == '...' || b.FkUserId == null
where c.FkTenderId == 2
select new {
a,
b,
c
};

Categories