Translate this Linq into SQL - sql

I have this linq code that I need to translate into identical SQL so I can query the database directly... I get stuck when it gets complicated. Can anyone help?
Linq
_db.BatchPaymentSplits
.Where(bps => bps.YearSetupId == i.YearSetupId)
.Where(bps => bps.CustomerIdEntered != null)
.Where(bps => _db.BatchPayments
.Where(bp => _db.Batches.Where(b => b.BatchTypeId.Equals("T"))
.Select(b => b.BatchId)
.Contains(bp.BatchId)
)
.Select(bp => bp.BatchPaymentId).Contains(bps.BatchPaymentId)
)
SQL so far
SELECT * FROM BatchPaymentSplit
WHERE YearSetupId = 1
AND CustomerIdEntered IS NOT NULL

I can't say that I think the LINQ or the resulting SQL is the best way to express this query (should be using Join I think), but this is my literal translation:
SELECT *
FROM BatchPaymentSplits bps
WHERE bps.YearSetupId = i.YearSetupId AND
bps.CustomerIdEntered IS NOT NULL AND
EXISTS (SELECT * FROM BatchPayments bp
WHERE EXISTS (SELECT * FROM Batches b
WHERE b.BatchTypeId = 'T' AND
b.BatchId = bp.BatchId) AND
bp.BatchPaymentId = bps.BatchPaymentId)
You can translate Contains when applied to an IEnumerable/IQueryable as an EXISTS query with an = expression.

Related

Convert Linq-to-SQL to SQL query

As I'm preparing a stored procedure, how can I do this in a SQL query?
This is my Linq-to-SQL code:
var passedContainers = Db.AssessmentContainers.Where(cac => cac.Assessments.All(a =>
completedContainers.FirstOrDefault(ac => ac.AssessmentId == a.AssessmentId) != null &&
completedContainers.FirstOrDefault(ac => ac.AssessmentId == a.AssessmentId).Earned));
Your question is quite a bit scarse, but with some guessing I think it could be something like that what you like to achieve:
SELECT * FROM AssessmentContainers A
INNER JOIN CompletedContainers C ON A.AssessmentId = C.AssessmentId
WHERE C.Earned = 1;
I don't have the full picture yet, but why would you like to do that with a stored procedure? Wouldn't a view be the better choice?

LINQ Lambda where in subquery

I´m trying do something like this :
Select * from A where id in (Select id_a from B)
But in LINQ
db.A().Join(db.B(), a => a.id, b => b.id_a, (a , b) => new { a, b}).....
I can do a JOIN. Is the best way? Or i have another options?.
I´m using Entity Framework
Thanks
From my SQL to LINQ recipe:
For translating SQL to LINQ query comprehension:
Translate subselects as separately declared variables.
Translate IN to .Contains() and NOT IN to !...Contains(), using literal arrays or array variables for constant lists.
SELECT * must be replaced with select range_variable or for joins, an anonymous object containing all the range variables.
So, for your SQL,
var id_aInB = from b in db.B select b.id_a;
var ans = from a in db.A where id_aInB.Contains(a.id) select a;
Using subquery in LINQ lambda
var q = db.A.Where(a=> db.B.Select(b=>b.id_a).toList().Contains(a.Id)).Select(a=>a);
In Linq there are many ways to express that. That SQL can also be expressed in different ways and probably the best is to use an EXISTS query instead, like:
Select * from A
where EXISTS (Select * from B where A.id = B.id_a)
That could be written in Linq as:
db.A.Where( a => db.B.Any( b => a.Id == b.Id_a ) );
Maybe you need this:
var result=db.A.Select(c=>new {c,listId=db.B.Select(s=>s.id_a)}).Where(w=>w.listId.Contains( w.c.id)).Select(c=>c.c);
Or you can use LINQ like this
from a in db.A
let listId = from b in db.B
select b.id_a
where listId.Contains(a.id)
select a
By the way, use LINQPad,you can get the right lamda by LINQ search

how to convert a sql having sub query in the from clause into Linq?

I have a sql statement as below, I want to translate it into Linq
select *
from
(
select Top 12 *
from DailyData
where ddaCode = '600000' and ddaDate < '2008/12/31'
order by ddaDate desc) as X
order by ddaDate
How can I do it? Thank you.
The From subquery becomes your first Linq query. Then this is queried in the second one.
var fromResults = DailyData.Where(x => x.ddaCode == "600000"
&& x.ddaDate < new DateTime(2008,12,31)
.OrderByDescending(x => x.ddaDate)
.Take(12);
var results = fromResults.OrderBy(x => x.ddaDate)

Entity framework join with a subquery via linq syntax

I'm trying to translate a sql query in linq sintax, but I'm having big trouble
This is my query in SQL
select * FROM dbo.ITEM item inner join
(
select SUM([QTA_PRIMARY]) QtaTotale,
TRADE_NUM,
ORDER_NUM,
ITEM_NUM
from [dbo].[LOTTI]
where FLAG_ATTIVO=1
group by [TRADE_NUM],[ORDER_NUM],[ITEM_NUM]
)
TotQtaLottiGroupByToi
on item.TRADE_NUM = TotQtaLottiGroupByToi.TRADE_NUM
and item.ORDER_NUM = TotQtaLottiGroupByToi.ORDER_NUM
and item.ITEM_NUM = TotQtaLottiGroupByToi.ITEM_NUM
where item.PRIMARY_QTA > TotQtaLottiGroupByToi.QtaTotale
and item.FLAG_ATTIVO=1
How can I translate into linq sintax?
This approach doesn't work
var res= from i in context.ITEM
join d in
(
from l in context.LOTTI
group l by new { l.TRADE_NUM, l.ORDER_NUM, l.ITEM_NUM } into g
select new TotQtaByTOI()
{
TradeNum = g.Key.TRADE_NUM,
OrderNum = g.Key.ORDER_NUM,
ItemNum = g.Key.ITEM_NUM,
QtaTotale = g.Sum(oi => oi.QTA_PRIMARY)
}
)
on new { i.TRADE_NUM, i.ORDER_NUM, i.ITEM_NUM} equals new { d.TradeNum, d.OrderNum, d.ItemNum }
I get this error
The type of one of the expressions in the join cluase is incorrect. Type inference failed in the call to 'Join'
Can you help me with this query?
Thank you!
The problem is Anonymous Type comparison. You need to specify matching property names for your two anonymous type's properties (e.g. first, second, third)
I tried it out, here's an example: http://pastebin.com/hRj0CMzs

Selecting from a table where field = this and value = that

I have a mysql table that looks something like this:
Row 1:
'visitor_input_id' => int 1
'name' => string 'country'
'value' => string 'Canada'
Row 2:
'visitor_input_id' => int 1
'name' => string 'province'
'value' => string 'Alberta'
Row 3:
'visitor_input_id' => int 1
'name' => string 'first_name'
'value' => string 'Jim'
The problem is that I need to be able to filter it so that a user can generate reports using this:
filter 1:
'field_name' => string 'country'
'field_operator' => string '='
'field_value' => string 'Canada'
filter 2:
'field_name' => string 'province'
'field_operator' => string '!='
'field_value' => string 'Alberta'
filter 3:
'field_name' => string 'first_name'
'field_operator' => string '%LIKE%'
'field_value' => string 'Jim'
I am not really sure what the query would look like to be able to select from this using the filters. Any suggestions? (Unfortunately, creating a new table to store the data more sanely is not really feasible at this time because it is already full of user data)
I think it would look something like this:
if(field_name = 'province' THEN ADD WHERE field_value != 'Alberta')
if(field_name = 'country' THEN ADD WHERE field_value = 'Canada')
if(field_name = 'first_name' THEN ADD WHERE field_value LIKE '%jim%')
but I am not sure how that would work...
Turns out that this seems to work:
SELECT * FROM visitor_fields
INNER JOIN visitor_inputs ON (visitor_inputs.input_id = visitor_fields.input_id)
INNER JOIN visitor_fields as filter_0
ON (filter_0.input_id=visitor_inputs.input_id
AND filter_0.field_name = 'province'
AND filter_0.field_value != 'Alberta')
INNER JOIN visitor_fields as filter_1
ON (filter_1.input_id=visitor_inputs.input_id
AND filter_1.field_name = 'country'
AND filter_1.field_value = 'Canada')
INNER JOIN visitor_fields as filter_2
ON (filter_2.input_id=visitor_inputs.input_id
AND filter_2.field_name = 'first_name'
AND filter_2.field_value LIKE '%jim%')
I know you say creating a new table with a better schema isn't feasible, but restructuring the data would make it more efficient to query and easier to work with. Just create a new table (called visitor in my example). Then select from the old table to populate the new visitor table.
vistor
----------------
vistor_id
firstname
province
country
You could loop through the statement below with any scripting language (PHP, TSQL, whatever scripting language you're most comfortable with). Just get a list of all vistor_id's and loop through them with the sql below, replacing the x with the visitor_id.
INSERT INTO visitor (visitor_id, name, province, country) VALUES X,
(SELECT value FROM old_table WHERE name='first_name' AND vistor_id = x),
(SELECT value FROM old_table WHERE name='province' AND vistor_id = x),
(SELECT value FROM old_table WHERE name='country' AND vistor_id = x);
This will produce a table where all a visitor's data is on a single row.
Are you able to create an SQL string and then execute it? The string would look like this:
SELECT * FROM yourtable
WHERE (name='country' AND value='Canada') AND
(name='province' AND value!='Alberta') AND
(name='first_name' AND value LIKE '%jim%)
EDIT:
I see. Multiple records. So try joining them. This is not correct SQL syntax but should look similar:
SELECT * FROM
(SELECT * FROM yourtable WHERE (name='country' AND value='Canada'))
JOIN on visitor_input_id
(SELECT * FROM yourtable WHERE (name='province' AND value!='Alberta'))
JOIN on visitor_input_id
(SELECT * FROM yourtable WHERE (name='first_name' AND value LIKE '%jim%))