SQL to Linq/Lambda - c#

Anyone can help me how to convert sql statement to linq and lambda like this ?
SELECT
tbl_terms.ID,
tbl_terms.Terms
FROM
tbl_terms
LEFT JOIN tbl_asn_uploaddoc ON tbl_terms.ID != tbl_asn_uploaddoc.Id_term
WHERE
tbl_asn_uploaddoc.Nip = '201948274838491943' && tbl_asn_uploaddoc.STATUS = 1
Thanks in advance

LINQ is mostly similar to SQL if you use query syntax instead of method syntax. Here is what I could gather quickly. Can't test because I don't have your model classes.
var Result = from t in context.tbl_terms
join d in context.tbl_asn_uploaddoc on t.ID != d.Id_term
where d.Nip = '201948274838491943' && d.STATUS = 1
select t.ID, t.Terms

Use below query that will give you LEFT JOIN on both of your entity,
var result = (from t in _con.tbl_Terms
join u in _con.tbl_asn_uploaddocs on t.ID equals u.Id_term
into tu
where !tu.Any()
from u in tu.DefaultIfEmpty()
where u.Nip == "201948274838491943" && u.STATUS == 1
select new
{
ID = t.ID,
Terms = t.Terms
}).ToList();
Where _con is your context.

You can use SQL to LINQ converter tool Linqer
Linqer is a SQL to LINQ conversion tool. It helps learning LINQ and convert existing SQL statements.

Related

Convert nested SQL query to LINQ Query

Is there a way to accurately convert the following SQL query to LINQ
SELECT * FROM T1
WHERE ColumnA IN (
SELECT FkColumnA FROM T2
WHERE FkColumnB IN (
SELECT ColumnB FROM T3
WHERE FkColumnC IN (
SELECT ColumnC FROM T4
WHERE FkColumnD = 1)) AND FkColumnE is null AND ColumnF = 0)
Also, does anyone know of any documentation wherein any logic or guideline to convert SQL queries to LINQ is laid out?
EDIT 1:
The equivalent for the above using JOINS would be as below:
select * from T1 a
inner join T2 b on a.FKColumnA = b.ColumnA
inner join T3 c on c.ColumnB = b.FkColumnB
inner join T4 d on d.ColumnC = c.FkColumnC
where a.FkColumnD is null and a.ColumnE = 0
and d.ColumnC = 1
and it's equivalent LINQ query would be
var linq = from q in context.T1
join r in context.T2
on q.FKColumnA equals r.ColumnA
join s in context.T3
on r.FkColumnB equals s.ColumnB
join t in context.T4
on s.FkColumnC equals t.ColumnC
where q.FkColumnD != null && q.ColumnE == false && t.ColumnC == 56816
select q.FkColumnF;
But using JOINS looked to be a bit more simpler and better in LINQ. Thus the question is for my knowledge purpose only.
Translating your query literally, we get the following LINQ statement:
var results = table1.Where(t1 => table2.Where(
t2 =>
table3.Where(
t3 =>
table4.Where(t4 => t4.FkColumnD == 1)
.Select(t4 => t4.ColumnC)
.Contains(t3.FkColumnC))
.Select(t3 => t3.ColumnB)
.Contains(t2.FkColumnB) && !t2.FkColumnE.HasValue && t2.ColumnF == 0)
.Select(t2 => t2.FkColumnA)
.Contains(t1.ColumnA));
This results in an IEnumerable<T1> which you can use as required.
As far as I know there is no "documentation" on converting syntax, this, as a developer, is your job. However, I personally find LINQPad very useful when constructing LINQ statements.

SQL Query to LINQ for MVC with SUM and IS NOT NULL

Can someone please help me convert this query to LINQ as I am new to using Linq which will then be used for google chart information.
Select Question.SubSectionName, SUM(Answers.RatingAnswer) AS Ratings
FROM Question,Answers,Response,Section
Where Answers.QuestionID = Question.QuestionID
AND Answers.ResponseID = Response.ResponseID
AND Question.SectionID=Section.SectionID
AND Section.SectionID = 2
AND Response.ResponseID = #0
AND Question.SubSectionName IS NOT Null
GROUP BY Question.SubSectionName;
What I've got so far :
var submitted = (from ans in db.Answers join ques in db.Questions on
ans.QuestionID equals ques.QuestionID
join resp in db.Responses on ans.ResponseID equals resp.ResponseID
join sec in db.Sections on ques.SectionID equals sec.SectionID
where sec.SectionID == 2 && resp.ResponseID == model.ResponseID
&& ques.SubSectionName!= null
select ques.SubSectionName && ans.RatingAnswer)
Thanks for any help.
Building on your comment this should output a grouping of sums of RatingAnswers:
var submitted =
(from ans in db.Answers
join ques in db.Questions on ans.QuestionId equals ques.QuestionId
join resp in db.Responses on ans.ResponseId equals resp.ResponseId
join sec in db.Sections on ques.SectionId equals sec.SectionId
where sec.SectionId == 2 && resp.ResponseId == model.ResponseID && ques.SubSectionName != null
select new { SubSectionName = ques.SubSectionName, RatingAnswer = ans.RatingAnswer })
.GroupBy(a => a.SubSectionName)
.Select(a => new { SectionName = a.Key, Sum = a.Sum(s => s.RatingAnswer) });
There may be a more efficient way of writing this.
I would also point out that to me the data structure seems flawed. That is, it seems either normalized incompletely or improperly. That's certainly for you to work out on your own.
Linqer helps you to convert SQL to LINQ.
If you want to get better in LINQ, I recommend using LINQPad. However, LINQPad can't convert from SQL to LINQ but from LINQ to SQL.
try this-
from q in Question
join a in Answers on q.QuestionID equals a.QuestionID
join r in Response on r.ResponseID equals a.ResponseID
join s in Section on s.SectionID equals q.SectionID
where s.SectionID= 2 and r.ResponseID= #0 and q.SubSectionName!=null
Group by q.SubSectionName

Use Array in Linq query

My question got down voted and put on hold because it is not specific enough. Ill try to specify
Before linq I would do this query
sql="SELECT products.* FROM products INNER JOIN productaccess ON products.id=productaccess.productid"
Now with the entity framework and link I can do this
var products = (from lProducts in db.Products
join lProductAccess in db.ProductAccess on lProducts.ID equals lProductAccess.ProductID
select lProducts).ToList();
But what if I want the flexibilty to get all products or only get the accessible objects
In sql I can do this
sql="SELECT products.* FROM products "
if (useProductAccess) {
sql+=" INNER JOIN productaccess ON products.id=productaccess.productid"
}
In Linq I have to make a separate linq statement.
if (useProductAccess) {
var productsFiltered = (from lProducts in db.Products
join lProductAccess in db.ProductAccess on lProducts.ID equals lProductAccess.ProductID
select lProducts).ToList();
} else {
var productsAll = (from lProducts in db.Products select lProducts).ToList();
}
Now, I could just get all the lProducts and then filter it in an additional linq statement with lProductAccess but then I am using an unnecessary large amount of data.
Is it an option to use:
var productsAccecible = (from lProductAccess in db.ProductAccess where lProductAccess.CustID==custID select lProductAccess).toArray();
var products = (from lProducts in db.Products
where (useProductAccess ?
productsAccessible.Contains(lProducts.ID)
: true)
select lProducts).ToList();
Linq provider will not know how to transform the ternary operator (? and :) in a valid sql, you could try this:
var query = db.Products;
if (useProductAccess)
query = query.Where(p => productsAccessible.Contains(p.ID));
var result = query.ToList();
I used the express profiler to see how the linq statement is translated into sql. It shows that the
productsAccessible.Contains(lProducts.ID)
part gets translated as
products.id in (comma seperated list of values)
My conclusion is it will work fine.
Are there possible drawbacks
Sure - it may produce an inefficient query, or it may not even work.
One thing to note is that your conditional operator won't compile; you can't return a bool and an int from the ternary operator.
Maybe you mean:
var products = (from lProducts in db.Products
where (useProductAccess ?
productsAccessible.Contains(lProducts.ID)
: true)
select lProducts).ToList();
or build your query up using method syntax and only add the where clause if necessary.

Conversion of SQL into LINQ

I need help converting some an SQL select into LINQ
Here is the original SQL:
Select Top 1 IsNull(ct.Template, t.Template) as Template
From Template t
Left Outer Join ClientTemplate ct On t.TemplateTypeId = ct.TemplateTypeId And ct.ClientId = 149
Where t.TemplateTypeId = (Select TemplateTypeId From QuoteType Where QuoteTypeId = 7)
Order By t.Version DESC, ct.Version DESC
I'm using Entity Framework and have entities for QuoteTypes, ClientTemplates and Templates.
The above SQL gets the Template from the ClientTemplate table for client 149 (uses a variable in the real code) for a particular QuoteType. If there is no entry in the CLientTemplate table then it returns the Template from the main Template table for the same QuoteType!
My idea was to query the QuoteType first and then query the ClientTemplate table to see if one exists and if not query the Template table instead. The problem is this will result in three queries but I'm sure it can be done in one swoop!?
Can anyone have a go at writing the LINQ for me?
Here's my mess so far:
QuoteType quoteType = (from qt in this.entities.QuoteTypes where qt.QuoteTypeID == this.SelectedNewQuoteTypeID select qt).First();
if (quoteType != null && quoteType.TemplateTypeID.HasValue)
{
int quoteTypeTemplateTypeID = (int)quoteType.TemplateTypeID;
var query = (from t in this.entities.Templates
join ct in this.entities.ClientTemplates on t.TemplateTypeID equals ct.TemplateTypeID
into a
from b in a.DefaultIfEmpty(new ClientTemplate())
where t.TemplateTypeID == quoteTypeTemplateTypeID
orderby t.Version descending
select new
{
T1 = t.Template1,
T2 = b.Template
}).First();
// Check the query to see if T1 and T2 are null and use whichever one isn't!
// TODO !!!
}
else
{
return string.Empty;
}
I kind of gave up once I got that far and posted this! My example still does two queries and does not select based on the client ID. It also does not have the second order by on the client template table.
I've inherited the original SQL statement so maybe the problem is with that being badly written in the first place!?
Over to you...
I haven't tested it but maybe you could try something like this
from t in this.entities.Template
from ct in this.entities.ClientTemplate.Where(x => t.TemplateTypeId == ct.TemplateTypeId && ct.ClientId == 149).DefaultIfEmpty()
where t.TemplateTypeId == (from x in this.entities.QuoteType where x.QuoteTypeId == 7 select x.TemplateTypeId).FirstOrDefault()
orderby t.Version descending, ct.Version descending
select new { ct.Template == null ? t.Template : ct.Template }
I think this might work, although this is untested, from reading it appears you can't add multiple join conditions to a LinQ statement so you can just specify it in the where clause
So here ya go, I tried to convert the SQL word for word so here's my attempt. If it does everything I think it will do it will work.
int templateTypeId;
templateTypeId= (context.QuoteType.Where(x => x.QuoteTypeId == 7)).FirstOrDefault().TemplateTypeId
var qry =(
from t in context.Template
join ct in context.ClientTemplate on
t.TemplateTypeId equals ct.TemplateTypeId into cts
from ct in cts.DefaultIfEmpty() //left join
where t.TemplateTypeId == templateTypeId
&& ct.ClientId == 149
order by t.Version descending, ct.Version descending
select new
{
Template = (ct.Template != null) ? ct.Template : t.Template //ternary operator
}).FirstOrDefault();

SQL query to linq syntax

How can i convert this join stmnt to linq syntax
SELECT pv.Product_ID, pv.Product, v.Add_ID, v.Product_ID
FROM Product AS pv
JOIN Product_Add AS v
ON ((pv.Product_ID = v.Add_ID) OR (pv.Product_ID = v.Product_ID))
where(( pv.Product_ID = v.Product_ID) OR (pv.product_ID = v.Add_ID))
Thanks
I would convert this for you
but its better you use this tool which is really help full to me to convert sql to linq code
http://www.sqltolinq.com/
just download and install on your machine will do work for you.
Instead of Join, you can use from...where, it's the same thing.
from pv in Product
from v in Product_Add
where ((pv.Product_ID == v.Add_ID) || (pv.Product_ID == v.Product_ID))
&&(( pv.Product_ID = v.Product_ID) || (pv.product_ID = v.Add_ID))
(You just AND all the join conditions with the rest of the where if you have multiple joins)

Categories