(from dtContract in dataEntity.contracts
where
(
dtContract.Supplier_ID == suppID &&
dtContract.Contract_Year != null
)
orderby dtContract.Contract_Year
select new
{
year = (int) dtContract.Contract_Year
}).ToList();
Above LINQ query is converted to following SQL query
SELECT
`Project1`.`Supplier_ID`, `Project1`.`C1`
FROM
`contracts` AS `Project1`
WHERE
(`Project1`.`Supplier_ID` = #p__linq__0)
AND (`Project1`.`Contract_Year` IS NOT NULL)
ORDER BY `Project1`.`Contract_Year` ASC;
Which is throwing exception
Unknown column C1
Can you please provide the reason behind this..?
Related
I have a Linq query that is joining on 2 nullable properties.
var result = (from A in context.TableA
join B in context.TableB
on A.ExecutionId equals B.ExecutionId
where B.InsertedBy == userName
Both rep.ExecutionId and sch.ExecutionId are nullable int in the database. What I really want Entity Framework to generate is
select
column1
from TableA A
inner join TableB B on A.ExecutionId = B.ExecutionId
where B.InsertedBy = #username
but what I get is
select
column1
from TableA A
inner join TableB B on A.ExecutionId = B.ExecutionId
OR ((A.[ExecutionId] IS NULL) AND (B.[ExecutionId] IS NULL))
where B.InsertedBy = #username
(Neither one of the ExecutionIds are primary keys). The second query gives me WAY more records than what I need, but more importantly, is not the query that I want. How can I write the LINQ so that it produces the first query or an equivalent?
If you do not want any records where ExecutionID is null, then use a filter
var result = (from A in context.TableA.Where( a => a.ExecutionID != null )
join B in context.TableB.Where( b => b.ExecutionId != null )
on A.ExecutionId equals B.ExecutionId
where B.InsertedBy == userName
...`enter code here`
i am intend to convert the following query into linQ
SELECT TOP 100 S.TxID,
ToEmail,
[Subject],
ProcessedDate,
[Status] = (CASE WHEN EXISTS (SELECT TxID FROM TxBounceTracking
WHERE TxID = S.TxID)
THEN 'Bounced'
WHEN EXISTS (SELECT TxID FROM TxOpenTracking
WHERE TxID = S.TxID)
THEN 'Opened'
ELSE 'Sent' END)
FROM TxSubmissions S
WHERE S.UserID = #UserID
AND ProcessedDate BETWEEN #StartDate AND #EndDate
ORDER BY ProcessedDate DESC
The following code is the linq that i converted.
v = (from a in dc.TxSubmissions
where a.ProcessedDate >= datefrom && a.ProcessedDate <= dateto && a.UserID == userId
let bounce = (from up in dc.TxBounceTrackings where up.TxID == a.TxID select up)
let track = (from up in dc.TxOpenTrackings where up.TxID == a.TxID select up)
select new { a.TxID, a.ToEmail, a.Subject,
Status = bounce.Count() > 0 ? "Bounced" : track.Count() > 0 ? "Opened" : "Sent",
a.ProcessedDate });
However this linq is too slow because the bounce and track table, how should i change the linq query to select one row only to match the SQL query above >>
SELECT TxID FROM TxOpenTracking WHERE TxID = S.TxID
in my selected column, so it can execute faster.
Note that the record contained one million records, thats why it lag
As you don't care about readability because you will end up generating the query via EF you can try to join with those two tables. (it looks that TxID is a FK or a PK/FK)
More about JOIN vs SUB-QUERY here: Join vs. sub-query
Basically your SQL looks like this:
SELECT TOP 100 S.TxID, ToEmail, [Subject], ProcessedDate,
[Status] = (CASE WHEN BT.TxID IS NOT NULL
THEN 'Bounced'
WHEN OP.TxID IS NOT NULL
THEN 'Opened'
ELSE 'Sent' END)
FROM TxSubmissions S
LEFT JOIN TxBounceTracking BT ON S.TxID = BT.TxID
LEFT JOIN TxOpenTracking OP ON S.TxID = OP.TxID
WHERE S.UserID = #UserID
AND ProcessedDate BETWEEN #StartDate AND #EndDate
ORDER BY ProcessedDate DESC
And then, you can try to convert it to LINQ something like:
v = (from subs in dc.TxSubmissions.Where(sub => sub.ProcessedDate >= datefrom && sub.ProcessedDate <= dateto && sub.UserID == userId)
from bts in dc.TxBounceTrackings.Where(bt => bt.TxID == subs.TxID).DefaultIfEmpty()
from ots in dc.TxOpenTrackings.Where(ot => ot.TxID == subs.TxID).DefaultIfEmpty()
select new { });
More about left join in linq here: LEFT JOIN in LINQ to entities?
Also if you remove default if empty you'll get a inner join.
Also you need to take a look at generated SQL in both cases.
Is there an easy way to do the following Nhibernate Linq statement
var query = from r in myTable.Query<MyTable>()
where r.Child == null
select r
The linq query above produces something similar to
SELECT MyTable.Id FROM MyTable WHERE MyTable.ChildId is null
it doesn't reference the child table and check if the left join is null like the following
SELECT MyTable.Id FROM MyTable
LEFT JOIN ChildTable ON MyTable.ChildId = ChildTable.Id
WHERE ChildTable.Id is null
var query = from r in myTable.Query<MyTable>()
where r.Child.Id == null
select r
Currently I need to copy records from Tabel1(SourceTable) to Table2(TargetTable) when record doesn't exist in Table2 along with few other condition .
I am using EntityFramework to do this job. When i used the below query to fetch records from source table i noticed Entity framework is using Left join with target table which is very slow, The same query when i replaced with not exist it worked fast.
so how to implement not exist in the below scenario?
Along with you can see 2 inner join with same table ? Why that so ?
In general how to overwrite EF generated query ?
We can do the above by mapping stored procedure but i am expecting without using SP mapping.
Query i have used to fetch :
var records = dal.SourceTransactions.Where((o) =>
o.Policy.Quote.Type == "1"
&& (o.TransactionType == 1 || o.TransactionType == 2 || o.TransactionType == 3 || o.TransactionType == 4)
&& o.TransactionDate < System.DateTime.Now &&
o.TargetTransaction == null);
generated EF query:
{SELECT
[Filter1].[ID1] AS [ID],
[Filter1].[TransactionDate] AS [TransactionDate],
[Filter1].[TransactionType] AS [TransactionType],
[Filter1].[PolicyId] AS [PolicyId]
FROM (SELECT [Extent1].[ID] AS [ID1], [Extent1].[TransactionDate] AS [TransactionDate], [Extent1].[TransactionType] AS [TransactionType], [Extent1].[PolicyId] AS [PolicyId]
FROM [dbo].[SourceTransactions] AS [Extent1]
INNER JOIN [dbo].[Policies] AS [Extent2] ON [Extent1].[PolicyId] = [Extent2].[ID]
INNER JOIN [dbo].[Quotes] AS [Extent3] ON [Extent2].[QuoteId] = [Extent3].[ID]
INNER JOIN [dbo].[Quotes] AS [Extent4] ON [Extent2].[QuoteId] = [Extent4].[ID]
WHERE ([Extent1].[TransactionType] IN (1,2,3,4)) AND
([Extent1].[TransactionDate] < (SysDateTime())) AND (N'1' = [Extent3].[Type]) AND ([Extent4].[Type] IS NOT NULL) )
AS [Filter1]
LEFT OUTER JOIN [dbo].[TargetTransactions] AS [Extent5] ON [Filter1].[ID1] = [Extent5]. [SourceTransactionID]
WHERE [Extent5].[SourceTransactionID] IS NULL}
You can force an EXISTS query like so:
dal.SourceTransactions
.Where(o => o.Policy.Quote.Type == "1"
&& (o.TransactionType == 1
|| o.TransactionType == 2
|| o.TransactionType == 3
|| o.TransactionType == 4)
&& o.TransactionDate < System.DateTime.Now
&& !dal.TargetTransactions
.Any(t => t.SourceTransactionID == o.ID)
So you explicitly create a subquery for the TargetTransactions. I assume that dal is a context instance, so it also exposes TargetTransactions.
Of course it's too bad that you have to massage EF into the best query. This may be one of the areas where EF 6 is improved, maybe worth a try.
I have a simple query:
var results = from k in db.tree_nodes
join s in db.stocks
on k.tree_nodes_id equals s.tree_nodes_id
into tmpTable
from rowtmp in tmpTable.DefaultIfEmpty()
select new
{
stock = (rowtmp.amount == null) ?
((k.code == null) ? (decimal?)null : (decimal?)0)
:
rowtmp.amount - rowtmp.amount_in_use,
};
This is the generated SQL code:
SELECT
(CASE
WHEN ([t1].[amount]) IS NULL THEN
(CASE
WHEN [t0].[code] IS NULL THEN CONVERT(Decimal(33,4),NULL)
ELSE CONVERT(Decimal(33,4),0)
END)
ELSE CONVERT(Decimal(33,4),[t1].[amount] - [t1].[amount_in_use])
END) AS [stock]
FROM [dbo].[tree_nodes] AS [t0]
LEFT OUTER JOIN [dbo].[stocks] AS [t1] ON [t0].[tree_nodes_id] = [t1].[tree_nodes_id]
The problem is, the generator created Decimal(33,4) when converting the results. So I'm getting "123.4560" in results instead of "123.456" All of my fields in this query are decimal(14,3). I don't mind the 33 part but I need to change the ,4 to ,3. How can I do this?
You could round the decimal values to 3 decimals?
var results = from k in db.tree_nodes
join s in db.stocks
on k.tree_nodes_id equals s.tree_nodes_id
into tmpTable
from rowtmp in tmpTable.DefaultIfEmpty()
select new
{
stock = (rowtmp.amount == null) ?
((k.code == null) ? (decimal?)null : (decimal?)0)
:
decimal.Round(rowtmp.amount,3) - decimal.Round(rowtmp.amount_in_use == null ? 0 : rowtmp.amount_in_use,3),
};
Dunno of any way to prevent linq-to-sql from type conversion.