Converting SQL to linq with a right join (advanced) - c#

I have the following SQL statement:
SELECT dh.*
FROM table1 w
LEFT OUTER JOIN table2 dh
on w.CBranch = dh.CBranch
AND w.CWorkstation = dh.CWorkstation
AND w.CNumber = dh.CNumber
RIGHT OUTER JOIN table3 dl
on dh.Id = dl.DispatchHeaderId
AND w.CLine = dl.CLine
AND w.CLineVersion = dl.CVersion
where w.ItemStatus = 9
AND dh.Shipping = 0
ORDER BY dh.CNumber ASC
I am beginner in Linq and not sure how to do advanced linq.
Could someone please guide me writing equivalent linq for this.
I am using C#, EF4.
I have managed to get till here, but not sure f this is correct.
var wos = scope.Context.table1.Where(
a => a.ItemStatus == (short)LineStatus.Packed)
.GroupBy(a => new { a.CNumber, a.CBranch, a.CWorkstation})
.Select(a => a.FirstOrDefault()).ToList();
var headerGroups = new List<IEnumerable<table2>>();
foreach(var status in wos)
{
if (status == null)
{
continue;
}
var headerList = scope.Context.table2s.Where(
b => b.CBranch == status.CBranch &&
b.CNumber == status.CNumber &&
b.CWorkstation == status.CWorkstation).ToList();
if (headerList != null && headerList.Any())
{
headerGroups.Add(headerList);
}
};

use defaultifemty() method in following link way....
http://smehrozalam.wordpress.com/2009/06/10/c-left-outer-joins-with-linq/

Related

Linq query equivalent of exists with multiple conditions

I've been using linq for a little while now but haven't come across this situation anywhere and my google-fu let me down.
Basically I have two data sets which I did not define and now have to use to return data.
class Header
{
string COMPANY_CODE
string REFERENCE_NBR
string REFERENCE_DUPLICATE
...
}
class Line
{
string COMPANY_CODE
string REFERENCE_NBR
string REFERENCE_DUPLICATE
string STOCK_CODE
string DESCRIPTION
...
}
From a database perspective they join like this
select *
from Header
inner join Line
on header.COMPANY_CODE = Line.COMPANY_CODE
and header.REFERENCE_NBR = Line.REFERNCE_NBR
and header.REFERENCE_DUPLICATE = LINE.REFERENCE_DUPLICATE
and have a 1:Many relationship.
I'm implementing a search feature for a listing that is meant to find any Lines that with a value in STOCK_CODE or DESCRIPTION that matches a given search term. I have seen a couple of methods of joining using a linq query but because of the multiple join conditions I'm a bit lost and have not found any examples of what I'm trying to do.
If I were to write the statement I am trying to get in lamda/linq in SQL it would be:
declare #searchtxt nvarchar(max) = 'test'
Select *
from header h
where exists (
select *
from Line l
where
(
l.stock_code like '%'+#searchtxt+'%'
or l.description like '%'+#searchtxt+'%'
)
and h.COMPANY_CODE = l.COMPANY_CODE
and h.REFERENCE_NBR = l.REFERENCE_NBR
and h.REFERENCE_DUPLICATE = l.REFERENCE_DUPLICATE
)
Any help would be appreciated!
Perhaps, this?
var result = header.Where(h =>
Line.Any(l => (l.stock_code.Contains(searchtxt)
|| l.description.Contains(searchtxt))
&& h.COMPANY_CODE == l.COMPANY_CODE
&& h.REFERENCE_NBR == l.REFERENCE_NBR
&& h.REFERENCE_DUPLICATE == l.REFERENCE_DUPLICATE));
This is a traditional LINQ query for better understanding,
string searchtext = "";
var result = (from h in context.Headers
join l in context.Lines on new { h.COMPANY_CODE, h.REFERENCE_DUPLICATE, h.REFERENCE_NBR } equals new { l.COMPANY_CODE, l.REFERENCE_DUPLICATE, l.REFERENCE_NBR }
where l.STOCK_CODE.Contains(searchtext) || l.DESCRIPTION.Contains(searchtext)
select new
{
COMPANY_CODE = h.COMPANY_CODE,
STOCK_CODE = l.STOCK_CODE
//You can select more fields from "h" and "l"
}).ToList();
Edit:
string searchtext = "";
var result = (from h in context.Headers
join l in context.Lines on new { h.COMPANY_CODE, h.REFERENCE_DUPLICATE, h.REFERENCE_NBR } equals new { l.COMPANY_CODE, l.REFERENCE_DUPLICATE, l.REFERENCE_NBR }
where l.STOCK_CODE.Contains(searchtext) || l.DESCRIPTION.Contains(searchtext)
select h
)
.GroupBy(x => new { x.COMPANY_CODE, x.REFERENCE_DUPLICATE, x.REFERENCE_NBR })
.Select(x => x.First())
.ToList();
db.Header.Join(
db.Line,
h => new { h.COMPANY_CODE, h.REFERENCE_NBR, h.REFERENCE_DUPLICATE },
l => new { l.COMPANY_CODE, l.REFERENCE_NBR, l.REFERENCE_DUPLICATE },
(h, l) => new
{
Header_COMPANY_CODE = h.COMPANY_CODE,
Header_REFERENCE_NBR = h.REFERENCE_NBR,
Header_REFERENCE_DUPLICATE = h.REFERENCE_DUPLICATE,
Line_Company_Code = l.COMPANY_CODE,
Line_REFERENCE_NBR = l.REFERENCE_NBR,
Line_REFERENCE_DUPLICATE = l.REFERENCE_DUPLICATE,
Line_STOCK_CODE = l.STOCK_CODE,
Line_DESCRIPTION = l.DESCRIPTION
}
)
.Where(w => w.Line_STOCK_CODE.Contains(searchText) || w.Line_DESCRIPTION.Contains(searchText))
.ToList();

Linq to SQL grouping with embedded lists causes too many queries

I am developing a query to grab and join some SQL tables in C# and am having some trouble with grouping and enumerables within the dataset. My query is below. This gives me the data in the format I'm looking for, but it takes way too long when I try to add the enumerated list as indicated below. When I look under the hood I can see it is executing way too many SQL queries. I'd like to get it to just one. Using LinqPad:
void Main()
{
var nightlyRuns = (from a in LoadTestSummaries
join b in LoadTestTestSummaryData
on a.LoadTestRunId equals b.LoadTestRunId
where a.TargetStack == "LoadEnv" &&
a.TestGuid != null &&
a.StartTime != null &&
a.LoadTestRunId != null
orderby a.StartTime
group new {a, b} by new
{
a.TestGuid,
a.Name,
a.Description,
a.StartTime,
a.Duration,
a.NumAgents,
a.NumHosts,
a.PassFail,
a.ResultsFilePath,
a.Splunk
}
into g
let scenarioStart = g.Min(s => s.a.StartTime) ?? g.Min(s => s.a.DateCreated)
let testCases = g.Select(s => s.b)
orderby scenarioStart
select new
{
TestGuid = g.Key.TestGuid,
ScenarioRun = new
{
Name = g.Key.Name,
Description = g.Key.Description,
StartTime = scenarioStart,
Duration = g.Key.Duration,
NumAgents = g.Key.NumAgents,
NumHosts = g.Key.NumHosts,
Result = g.Key.PassFail,
ResultsFilePath = g.Key.ResultsFilePath,
SplunkLink = g.Key.Splunk,
// PROBLEM: Causes too many queries:
TestRuns = from t in testCases select t.TestCaseId
}
}).ToLookup(g => g.TestGuid, g => g.ScenarioRun);
nightlyRuns["ba593f66-695f-4fd1-99c3-71253a2e4981"].Dump();
}
The "TestRuns" line is causing the excessive queries. Any idea what I am doing wrong here?
Thanks for any insight.
Tough answer to test but I think we can avoid the grouping and multiple queries with something like this: (https://msdn.microsoft.com/en-us/library/bb311040.aspx)
var nightlyRuns = (from a in LoadTestSummaries
join b in LoadTestTestSummaryData
on a.LoadTestRunId equals b.LoadTestRunId
where a.TargetStack == "LoadEnv" &&
a.TestGuid != null &&
a.StartTime != null &&
a.LoadTestRunId != null
into testGroup
select new
{
TestGuid = a.TestGuid,
ScenarioRun = new
{
Name = a.TestGuid,
Description = a.Description,
StartTime = a.StartTime ?? a.DateCreated,
Duration = a.Duration,
NumAgents = g.Key.NumAgents,
NumHosts = a.NumHosts,
Result = a.PassFail,
ResultsFilePath = a.ResultsFilePath,
SplunkLink = a.Splunk,
// PROBLEM: Causes too many queries:
TestRuns =testGroup
}
}).OrderBy(x=>x.StartTime).ToLookup(x => x.TestGuid, x => x.ScenarioRun);
nightlyRuns["ba593f66-695f-4fd1-99c3-71253a2e4981"].Dump();

To many nested statements

I have a c# code as follows
var deptSalesQuery =
from d in db.DashboardFigures
join s in outlets.Split(',').Select(x => int.Parse(x)) on d.OutletNo equals s
where (d.TypeOfinformation == "SALES")
group d by new
{
d.Number
} into newGroupedresult
select new DeptSales()
{
Dn = (int)newGroupedresult.Key.Number,
Qs = (double)newGroupedresult.Sum(d => d.Value_4),
Se = (double)newGroupedresult.Sum(d => d.Value_2),
Si = (double)newGroupedresult.Sum(d => d.Value_3)
+ (double)newGroupedresult.Sum(d => d.Value_2)
};
When I pass in Outlets = "1,2,3,4,....all the way upto 110", the software crashes telling me that there are too many nested statements.
Is there any way that I can remove the JOIN and add something onto the WHERE clause to help the situation?
Thanks
As written by juharr, before the query do:
int[] splitted = outlets.Split(',').Select(int.Parse);
and in the query:
where splitted.Contains(d.OutletNo) && d.TypeOfinformation == "SALES"

how to use Linq " NOT IN"

I'm using Entity Framework
So I want to write a sql command using two tables - tblContractor and tbSiteByCont tables.
It looks like this in SQL
SELECT PKConID, Fname, Lname
FROM tblContractor
WHERE (PKConID NOT IN
(SELECT FKConID
FROM tbSiteByCont
WHERE (FKSiteID = 13)))
but I don't know how to write in Linq.
I tried like this
var query1 = from s in db.tblSiteByConts
where s.FKSiteID == id
select s.FKConID;
var query = from c in db.tblContractors
where c.PKConID != query1.Any()
select Contractor;
But this doesn't work.
So how should I write it? What is the procedure? I'm new to Linq.
var _result = from a in tblContractor
where !(from b in tbSiteByCont
where FKSiteID == 13
select b.FKConID)
.Contains(a.PKConID)
select a;
or
var siteLst = tbSiteByCont.Where(y => y.FKSiteID == 13)
.Select(x => x.FKConID);
var _result = tblContractor.Where(x => !siteLst.Contains(x.PKConID));
I'd use a HashSet, it ensures you only evaluate the sequence once.
var result = from p in tblContractor
let hasht = new HashSet<int>((from b in tbSiteByCont
where b.FKSiteID == 13
select b.PKConID).Distinct())
where !hasht.Contains(p.PKConID)
select p;
may this work too
var _result = from a in tblContractor
.Where(c => tbSiteByCont
.Count(sbc => sbc.FKSiteID == 13 && c.PKConID == sbc.FKConID) == 0)

How Convert this T-SQL to LINQ

I have the following SQL statement
SELECT [CodeHouse]
,[CodeReq]
,[Address]
FROM [ShahrdariProject].[dbo].[House]
where [CodeReq] in
(select [CodeReq] From [ShahrdariProject].[dbo].[HouseOwner] where [Name] = 'Alex' )
Can anyone please help me to convert this statement to LINQ?
This SQL:
SELECT [CodeHouse]
,[CodeReq]
,[Address]
FROM [ShahrdariProject].[dbo].[House]
where [CodeReq] in
(select [CodeReq] From [ShahrdariProject].[dbo].[HouseOwner]
where [Name] = 'Alex' )
Is equivalent to this Linq:
var q = from h in db.Houses
where db.HouseOwners.Any(x => x.Name == "Alex" && x.CodeReq == h.CodeReq)
select h;
using(var dbContext = new /**Your Linq DataContext class here**/())
{
var results = dbContext.House.Join(
dbContext.HouseOwner.Where(ho => ho.Name == "Alex"),
h => h.CodeReq,
ho => ho.CodeReq,
(h, ho) => select new { h.CodeHouse, h.CodeReq, h.Address }).ToArray();
}
EDIT: Based on your query, I figured it would be oK to express the query using a JOIN instead of using IN
List<string> codeReq = new List<string>();
using(DemoDataContext db = new DemoDataContext()){
var houses = from h db.Houses where codeReq.Contains(h.codeReq) selec h;
}
Try to use the following code, i am sure this resolve your issue
var result = from house in db.Houses
where db.HouseOwners.Any(z => z.Name == "Alex" && z.CodeReq == house.CodeReq)
select house;
Enjoy......

Categories