LINQ translation doesn't give the same results as my SQL query - sql

Hi guys I have this SQL query (MSSQL), I'm doing a query where the result of joins are giving me the "top" row of newest row by date without having duplicates of results, you can find here information of what I'm doing http://goo.gl/Uv0FR The thing is this, I accomplished already the SQL query, Is Working as I'm expecting, I'm getting 1 row for each IDKEY uses in the clause "where pi.PlazaIe in ('','') without duplication
Select * from PlazaI pi
join (
Select * from PlazaE pe where
NOT EXISTS(SELECT 1 FROM PlazaE pe1
WHERE pe.Id_plaza = pe1.Id_plaza AND pe1.Fecha > pe.Fecha AND pe1.Fecha < GETDATE() and pe1.Id_Emp != 0)
) pe on pe.Id_plaza = pieepo.Id_plaza
join Emp e on pe.Id_Emp = e.Id_Emp
join View ct on ct.Id_Nodo = pe.id_nodo
where pi.PlazaIe in ('value1','value2')
The PROBLEM is when I'm trying to convert from SQL to LINQ is just can't make to happened. (I'm new in this world of Linq)
the following is my linq query.
var q1 = (from pe in db.PlazaEmpleados
where !db.PlazaEmpleados.Any
(
pe1 => (pe1.Id_plaza.Equals(pe.Id_plaza) && pe1.Fecha > pe.Fecha && pe1.Id_Emp != 0 && pe1.Fecha > DateTime.Now)
) select pe);
var q2 = (from pi in db.Context
join pe in (q1) on pi.Id_plaza equals pe.Id_plaza
select new EmpVO
{
Id_Nodo = pe.id_nodo,
Id_plaza = pi.PlazaSome,
Num_Plaza = pi.Id_plaza,
});
When I run this linq2sql query I'm getting duplicate results instead of just 1 for each value. So the thing is, I would like to know if someone can convert in a good way the SQL query to LINQ Query or point me where is the error.
thanks in advance.

Your check for the Date is different:
LINQ:
pe1.Fecha > DateTime.Now
SQL:
pe1.Fecha < GETDATE()
Isnt your LINQ supposed to be:
pe1.Fecha < DateTime.Now

I didn't find answer which resolve my problem, so what I finally did is to use the
db.ExecuteQuery<ObjectVO>(sqlQuery);
I know this is not the best practice and also don't resolve the question why my sql query and my linq query don't get the same result set, but non of the previous answer did.
The other thing is my query grown in complexity (new business logic requirement) have to join 7 table and search for Max dates and movement is some of them, so now is more complicated to transform the query to a linq to sql.
Thanks for the support.

this part:
var q1 = from pe in db.PlazaEmpleados
where !db.PlazaEmpleados.Any
(pe1 =>
pe1.Id_plaza.Equals(pe.Id_plaza) &&
pe1.Fecha > pe.Fecha &&
pe1.Id_Emp != 0 &&
pe1.Fecha < DateTime.Now
)
select pe;
In SQL you first use PlazaI then PlazaE- in Linq you both times use PlazaEmpleados.

Put your SQL query to stored procedure an add it to context. Then just call:
var q = context.MyProcedure(new object[] {"value1","value2"});

Related

Query on other query linq

Just assume a simple example:I have two table and use this query:
select *
from People
where PersonGuid = (select PersonGuid from Sellers where Guid = '')
How can I write this query with linq?
I tried this:
var person = from p in loginContext.Person where p.PersonGuid =
(loginContext.Seller.Where(s => s.Guid == sellerGuid).FirstOrDefaultAsync());
but that's wrong.
What is the right way to write it?
If you were to rewrite your SQL query as
select *
from People AS PE
JOIN
Sellers AS Sellers
ON PE.PersonGuid = SE.PersonGuid
WHERE
SE.Guid = ''
then the LINQ becomes a little more obvious:
var person = (from p in loginContext.Person
join s in loginContext.Seller on p.PersonGuid equals s.PersonGuid
where s.guid == ""
select p)
.FirstOrDefault();
Although your SQL would suggest FirstOrDefault is not required.
Warning - not tested.
You could probably try using LINQ JOIN clause.
It should be something like:
from p in loginContext.Person
join s in loginContext.Seller on new { p.PersonGuid = s.Guid }
where s.Guid = sellerGuid
You can know more about LINQ JOIN here -> Microsoft C# Reference
Hope it helps!
I will assume that select PersonGuid from Sellers where Guid = '' will provide a single value no matter what, otherwise your SQL statement would fail.
Accepted answer works, but if you want a solution that keeps the spirit of the SQL query, you can rely on Any function. Something along the following:
var person = await loginContext.Person
.Where(p => loginContext.Sellers
.Any(s => s.PersonGuid == p.PersonGuid && s.Guid = ""))
.FirstOrDefaultAsync();
I expect this to be transformed into an SELECT ... WHERE EXISTS which is similar to your initial query.

How to write sub query using linq in mvc5?

I am writing my sub query using linq in my application. I wrote my sql sub-query in sql server. When I execute this query in SQL Server the result give perfect and the sql query will be like
My SQL Server:
select Row_Number() Over(OrderBy Mmname) as Sno,Mmname,Mmcardno,Mmdob,MmEmail,(Select SUM(MSSRNETAMT) from MSCAS where MSCAS.MSSFORMNO = MSMEM.MmCardno and MSCAS.MSSRBILLDT between '01/01/2016' and '30/12/2016') Billopen,(Select SUM(MSSRNETAMT) from MSCAS where MSCAS.MSSFORMNO = MSMEM.MmCardno and MSCAS.MSSRBILLDT between '01/01/2016' and '30/12/2016') BillForm,Mmredpv,Msdval,Mmcontact,Mmdate,Mmaddr,MmCuser,MmCuserdt,Mmusercd,
Mmuser,Mmuserdt,Cast(Mmcntrn as int ) as Mmcntr from MSMEM inner join MSSCHEDET on MSMEM.Mschuid = MSSCHEDET.MSDID
My linq query
Var query = (from Ms in db.msmems join Mss in db. Msschedet on Ms. Mechuid equals mss. MSDID select new
{
name = Ms. Mmname,
Billopen = (from mc in db. MSCAS where Ms. Mmcardno = mc. Mssformno) select mc.MSSRNETAMT);
}):
This only I tried but I am getting error in bill open it is amount in that I am getting error
This is my SQL query. I tried to convert this sql query in linq. But I am failed many times, I got an error.
Could you try something like this? Without understanding your table structure better, I took a shot at optimizing this. Is there no reason that you couldn't do a second join to your MSCAS table?
var query = (from Ms in db.msmems
join Mss in db.Msschedet on Ms.Mechuid equals mss.MSDID
join Mc in db.MSCAS on Ms.Mmcardno equals Mc.Mssformno
select new {
name = Ms.Mmname,
Billopen = Mc.where(x=>x.MSSRBILLDT >= '01-01-2016' and x.MSSRBILLDT <= '12-30-2016').Sum(z=>z.MSSRNETAMT)
}
);

Convert SQL with multiple join into LINQ

I would like to know how can i change the following sql statement into Linq or Lambda Extension in C#
SELECT m.mdes as AgeGroup,COUNT(DISTINCT(mbcd))as "No.of Member" FROM mageg m
LEFT JOIN (select distinct(mbcd) ,mage
FROMtevtl
JOIN mvipm
ON tevtl.mbcd = mvipm.mvip
WHERE datm >= '2014-04-01'
AND datm <= '2014-04-30'
)vip
ON m.tage >= vip.mage AND m.fage <= vip.mage
GROUP BY m.mdes
I manage to do the first half of the LINQ statement. Not sure If it is correct
here is the first half. I do not know how to connect with the left join.
(from mem in mvipms
from log in tevtls
from grp in magegs
where mem.mage >=grp.fage && mem.mage <=grp.tage && mem.mvip.Equals(log.mbcd)
&& log.datm >= DateTime.Parse("2014-04-01") && log.datm <= DateTime.Parse("2014-04-30")
select new {mem.mvip,grp.mdes}).Distinct()
Pls advice. I am using the MSSQL 2008 and VS2010.
Thanks a million.
I am no expert on LINQ, but since no-one else has answered, here goes!
Firstly you cannot (AFAIK) do a LINQ join on anything other than equals so the structure of your LEFT JOIN has to change. Partly for debugging purposes, but also for readability, I prefer to layout my LINQ in bite-size chunks, so what I would do in your case is something like this (assuming I have understood your data structure correctly):
var vip = (from t in tevtl
join v in mvipl
on t.mbcd equals v.mvip
where t.datm >= new DateTime(2014, 4, 1) && t.datm <= new DateTime(2014, 4, 30)
select new { t.mbcd, v.mage }).Distinct();
var mv = from m in magegl
from v in vip
where m.tage >= v.mage && m.fage <= v.mage
select new
{
m.mdes,
v.mbcd
};
var gmv = from m in mv
group m by new { m.mdes } into grp
select new
{
mdes = grp.Key.mdes,
CountMBCD = grp.Count()
};
var lj = from m in magegl
join v in gmv
on m.mdes equals v.mdes into lhs
from x in lhs.DefaultIfEmpty()
select new
{
AgeGroup = m.mdes,
CountMBCD = x != null ? x.CountMBCD : 0
};
By way of explanation. mv is the equivalent structure for your left join in that it has the relevant where clause, but obviously it does not contain any nulls - it is equivalent to an INNER JOIN. gmv is a group on mv, so is still effectively an INNER JOIN. Then to pick up the missing mdes (if any) I re-join on magel with the added syntax DefaultIfEmpty() - this converts the join into the equivalent of a LEFT OUTER JOIN.
Without any sample data, I haven't been able to test this, but I hope it gives you enough to point you in the right direction!

Create a LINQ for SQL query

I'm learning Linq and using MVC. I have written a SQL query which I need to convert to a LINQ query.
select TokenID,TokenAsset,packet from TokenTable where id = 6 and packet = ''
and TokenID not in (select TokenID from TokenTable where id=6 and packet <> '')
group by TokenID,TokenAsset,Packet
I kindly ask help to convert the above query to a LINQ query. I know that the SQL query isn't efficient. It would better if you can help me to fix it.
Try this one:
var result = Tokens.Where(x=>x.Id==6 &&
x.Packet=="" &&
!Tokens.Exists(y=>y.TokenID==x.TokenID &&
y.Id==6 &&
y.Packet!="")
)
.GroupBy(x=>x.ID)
.ThenGroupBy(x=>x.TokenAsset)
.ThenGroupBy(x=>x.Packet);
Note I suppose that collection Tokens holds all the tokens you have.
Firstly your SQL query can just be
select distinct TokenID, TokenAsset, packet
from TokenTable
where id = 6 and packet = ''
the group by is not that useful since there are no aggregated columns. All selected columns are in the group by clause. Use distinct to achieve the same.
the secondary AND condition for tokenid is also redundant. It is exclusive to the first condition and hence doesn't change the result.
use this LINQ query:
var results = dbcontext.TokenTables
.Where(t => t.id == 6 && t.Packet == "")
.Select(t => new { t.TokenId, t.TokenAsset, t.Packet }).Distinct();
project only columns you need for performant calls by avoiding extra data transfer.

Giving different record set after changing simple SQL query to LINQ query

I have write the below query in simple SQL,
I want to change it to use LINQ, I have tried, but my LINQ query and the original SQL statement are giving different record sets.
Simple SQL Query:
select *
from Paymentadvices
where status = 3
and Id in (select PaymentAdviceId from Approvals where ApprovedById = 13)
LINQ:
var myPaymentAdviceList = from pa in db.PaymentAdvices
where pa.Status == 3
join Ap in db.Approvals on pa.Id equals
Ap.PaymentAdviceId
where Ap.EmployeeId == 13
orderby pa.PaidDate descending
select pa;
I am not supposed to use join I guess, What should I use ?
var a = db.Approvals.Where( x => x.ApprovalById = 13).PaymentAdviceId;
var b = db.Paymentadvices.Where(x => x.status ==3 && a.Contains(x.Id);
.Contains() makes the WHERE IN () , you don't need a join there
var a = from a in db.Approvals
where a.ApprovedById == 3
select a.PaymentAdviceId;
var b = (from p in db.PaymentAdvices
where p.Status == 3 &&
a.Contains(p.Id)
select p).ToList();
those are both linq , the top is just lambda expressions which are commonly used in Linq queries. I would reccommend that you get used to reading/ writing both styles . The majority of code you'll come across in lambda style
I believe something like the below would work:
var query = from p in db.PaymentAdvices
where p.Status == 3 && db.Approvals
.Select(a => a.Id)
.Where(a => a.ApprovedById == 13)
.Contains(p.Id)
select p;
Though it's worth noting that #Scott Selby and #axrwkr solutions above are essentially the exact same thing in another form.