LINQ with Conditional Left Join - vb.net

Hi there i am a newbie in linq,
i tried to do a left join query using LinQ. This is my query:
SELECT B.[ID]
,A.[GroupID]
,B.[Year]
,B.[Month]
,B.[Col1]
,B.[Col2]
,B.[Col3]
,B.[Col4]
,B.[Col5] FROM MsGroups A
LEFT JOIN MsCKPNS B on
A.GroupId = B.GroupId and B.Year = 2014 and B.Month = 3
Here is my linq query:
Dim msckpn = (From g In db.MsGroup
Group Join c In db.MsCKPNs
On g.GroupId Equals c.GroupID Into
Group From a In Group.DefaultIfEmpty() _
Where a.Month = Month And a.Year = Year
Select New MsCKPN With {
.ID = Nothing,
.GroupID = g.GroupId,
.Month = Month,
.Year = Year,
.Col1 = a.Col1,
.Col2 = a.Col2,
.Col3 = a.Col3,
.Col4 = a.Col4,
.Col5 = a.Col5
}).ToList
But, it shows error : The entity or complex type 'MvcMISD.MsCKPN' cannot be constructed in a LINQ to Entities query.
What should i do to fix the query?
Thanks

You can't create an entity like this. The reason is that you are not supposed to be able to create an entity which isn't linked to a record or records in the database. An explanation of this is given in the comments below this answer: https://stackoverflow.com/a/5325861/1737957 You can create an anonymous type which has the fields you want.
Some other parts of your code look a little strange but I'm not so familiar with LINQ in VB so I could be misunderstanding your query.

Related

Need help in optimizing sql query

I am new to sql and have created the below sql to fetch the required results.However the query seems to take ages in running and is quite slow. It will be great if any help in optimization is provided.
Below is the sql query i am using:
SELECT
Date_trunc('week',a.pair_date) as pair_week,
a.used_code,
a.used_name,
b.line,
b.channel,
count(
case when b.sku = c.sku then used_code else null end
)
from
a
left join b on a.ma_number = b.ma_number
and (a.imei = b.set_id or a.imei = b.repair_imei
)
left join c on a.used_code = c.code
group by 1,2,3,4,5
I would rewrite the query as:
select Date_trunc('week',a.pair_date) as pair_week,
a.used_code, a.used_name, b.line, b.channel,
count(*) filter (where b.sku = c.sku)
from a left join
b
on a.ma_number = b.ma_number and
a.imei in ( b.set_id, b.repair_imei ) left join
c
on a.used_code = c.code
group by 1,2,3,4,5;
For this query, you want indexes on b(ma_number, set_id, repair_imei) and c(code, sku). However, this doesn't leave much scope for optimization.
There might be some other possibilities, depending on the tables. For instance, or/in in the on clause is usually a bad sign -- but it is unclear what your intention really is.

How do I fix the syntax of a sub query with joins?

I have the following query:
SELECT tours_atp.NAME_T, today_atp.TOUR, today_atp.ID1, odds_atp.K1, today_atp.ID2, odds_atp.K2
FROM (players_atp INNER JOIN (players_atp AS players_atp_1 INNER JOIN (today_atp INNER JOIN odds_atp ON (today_atp.TOUR = odds_atp.ID_T_O) AND (today_atp.ID1 = odds_atp.ID1_O) AND (today_atp.ID2 = odds_atp.ID2_O) AND (today_atp.ROUND = odds_atp.ID_R_O)) ON players_atp_1.ID_P = today_atp.ID2) ON players_atp.ID_P = today_atp.ID1) INNER JOIN tours_atp ON today_atp.TOUR = tours_atp.ID_T
WHERE (((tours_atp.RANK_T) Between 1 And 4) AND ((today_atp.RESULT)="") AND ((players_atp.NAME_P) Not Like "*/*") AND ((players_atp_1.NAME_P) Not Like "*/*") AND ((odds_atp.ID_B_O)=2))
ORDER BY tours_atp.NAME_T;
I'd like to add a field to this query that provides me with the sum of a field in another table (FS) with a few criteria applied.
I've been able to build a stand alone query to get the sum of FS by ID_T as follows:
SELECT tbl_Ts_base_atp.ID_T, Sum(tbl_Ts_mkv_atp.FS) AS SumOfFS
FROM tbl_Ts_base_atp INNER JOIN tbl_Ts_mkv_atp ON tbl_Ts_base_atp.ID_Ts = tbl_Ts_mkv_atp.ID_Ts
WHERE (((tbl_Ts_base_atp.DATE_T)>Date()-2000 And (tbl_Ts_base_atp.DATE_T)<Date()))
GROUP BY tbl_Ts_base_atp.ID_T, tbl_Ts_mkv_atp.ID_Ts;
I now want to match up the sum of FS from the second query to the records of the first query by ID_T. I realise I need to do this using a sub query. I'm confident using these when there's only one table but I consistently get 'syntax errors' when there are joins.
I simplified the first query down to remove all the WHERE conditions so it was easier for me to try and error check but no luck. I guess the resulting SQL will also be easier for you guys to follow:
SELECT today_atp.TOUR, (SELECT Sum(tbl_Ts_mkv_atp.FS)
FROM tbl_Ts_mkv_atp INNER JOIN (tbl_Ts_base_atp INNER JOIN today_atp ON tbl_Ts_base_atp.ID_T = today_atp.TOUR) ON tbl_Ts_mkv_atp.ID_Ts = tbl_Ts_base_atp.ID_Ts AS tt
WHERE tt.DATE_T>Date()-2000 And tt.DATE_T<Date() AND tt.TOUR=today_atp.TOUR
ORDER BY tt.DATE_T) AS SumOfFS
FROM today_atp
Can you spot where I'm going wrong? My hunch is that the issue is in the FROM line of the sub query but I'm not sure. Thanks in advance.
It's difficult to advise an appropriate solution without knowledge of how the database tables relate to one another, but assuming that I've correctly understood what you are looking to achieve, you might wish to try the following solution:
select
tours_atp.name_t,
today_atp.tour,
today_atp.id1,
odds_atp.k1,
today_atp.id2,
odds_atp.k2,
subq.sumoffs
from
(
(
(
(
today_atp inner join odds_atp on
today_atp.tour = odds_atp.id_t_o and
today_atp.id1 = odds_atp.id1_o and
today_atp.id2 = odds_atp.id2_o and
today_atp.round = odds_atp.id_r_o
)
inner join players_atp as players_atp_1 on
players_atp_1.id_p = today_atp.id2
)
inner join players_atp on
players_atp.id_p = today_atp.id1
)
inner join tours_atp on
today_atp.tour = tours_atp.id_t
)
inner join
(
select
tbl_ts_base_atp.id_t,
sum(tbl_ts_mkv_atp.fs) as sumoffs
from
tbl_ts_base_atp inner join tbl_ts_mkv_atp on
tbl_ts_base_atp.id_ts = tbl_ts_mkv_atp.id_ts
where
tbl_ts_base_atp.date_t > date()-2000 and tbl_ts_base_atp.date_t < date()
group by
tbl_ts_base_atp.id_t
) subq on
tours_atp.tour = subq.id_t
where
(tours_atp.rank_t between 1 and 4) and
today_atp.result = "" and
players_atp.name_p not like "*/*" and
players_atp_1.name_p not like "*/*" and
odds_atp.id_b_o = 2
order by
tours_atp.name_t;

SQL to LINQ with outer joins and count

I am trying to write the LINQ statement for the following OUTER JOIN with COUNT but can't seem to work it out..
My LINQ skills aren't what they should be yet so any pointer would be greatly appreciated.
The SQL statement in question is:
SELECT b.Id,
b.Text,
b.Active,
COUNT(u.BusinessArea_Id)
FROM dbo.[User] AS u RIGHT OUTER JOIN dbo.BusinessArea AS b ON b.Id = u.BusinessArea_Id
GROUP BY b.Id, b.Text, Active
ORDER BY b.Id
I think you can use a linq like this:
var res = (from ba in businessAreas
let count = users.Count(u => u.BusinessArea_Id == ba.Id)
orderby ba.Id
select new {ba.Id, ba.Text, ba.Active, Count = count}
).ToList();

I'm trying to update the data in table column "Supplier_Base.CreditBalance" with the sum of the colum "Purch" in table "Suppliers_Account"

This was what i'm trying but it does not work.
UPDATE
dbo.Supplier_Base SET dbo.Supplier_Base.CreditBalance (
SELECT
SUM(dbo.Suppliers_Account.Purch ) AS BAL,
FROM
dbo.Suppliers_Account
INNER JOIN
dbo.Supplier_Base ON dbo.Suppliers_Account.Code = dbo.Supplier_Base.Code
GROUP BY dbo.Suppliers_Account.Code, dbo.Supplier_Base.CreditBalance
HAVING (dbo.Suppliers_Account.Code = N'C003'))
Sub-queries aren't allowed in a SET statement. You can work around this by aliasing the tables and doing a JOIN instead.
Do you have a test environment where you can run queries with damaging production data? I think this is what you're looking for, but DO test it first:
UPDATE
b
SET
b.CreditBalance = SUM(a.Purch)
FROM
dbo.Suppliers_Account a
INNER JOIN
dbo.Supplier_Base b
ON
a.Code = b.Code
WHERE
a.Code = N'C003'
GROUP BY
a.Code
This is the correct syntax:
UPDATE SB
SET CreditBalance = SA.Purch
FROM dbo.Supplier_Base SB
INNER JOIN (SELECT Code, SUM(Purch) Purch
FROM dbo.Suppliers_Account)
GROUP BY Code) SA
ON SB.Code = SA.Code
WHERE SB.Code = N'C003'

Help converting SQL query to JPQL

I have a SQL query that I need to translate over into JPQL, and I'm beginning to wonder if this is one of the cases where I'll just have to use native SQL. For reference, here is the SQL query.
SELECT c.title, a.approval_total, r.requested_total
FROM
codes c
INNER JOIN
(SELECT code_id, year, SUM(requested_amount) requestedTotal
FROM requests
GROUP BY code_id, year) r
ON c.id = r.code_id
INNER JOIN
(SELECT code_id, year, SUM(approved_amount) approvedTotal
FROM approvals
GROUP BY code_id, year) a
ON c.id = a.code_id
WHERE c.title = ? AND r.fiscal_year = ? and a.fiscal_year = ?
Does anyone know of a way to translate an in line view like these two into JPQL? Or alternatively a different way of structuring the query that might make it easier to translate?
I would first rewrite the SQL query without the use of inline selects
not sure if I write it correctly, but it would be something like this :
SELECT c.title, sum(a.approved_amount) as approval_total, SUM(r.requested_amount) as requested_total
FROM codes c
INNER JOIN requests r ON c.id = r.code_id
INNER JOIN approvals a ON c.id = a.code_id
WHERE c.title = ? AND r.fiscal_year = ? and a.fiscal_year = ?
GROUP By r.code_id, r.year, a.code_id, a.year