Help needed on SQL query to Linq Conversion - linq

Please help me write LINQ for this SQL
select svc.SvcName, svcOptions.SvcOptionName, svcMap.Price from svcMap
inner join
svc
on svcMap.SvcId = svc.SvcId
inner join
svcOptions
on svcOptions.SvcOptionId = CASE WHEN (svcMap.DesiredSvcOptionId <> 0 AND svcMap.DesiredSvcOptionId <> svc.DisabledSvcOptionId) THEN
svcMap.DesiredSvcOptionId
WHEN (svcMap.PresentSvcOptionId <> svc.DisabledSvcOptionId) THEN
svcMap.PresentSvcOptionId
ELSE
0
END
where svcMap.ToBill = 1
and
(
(svcMap.DesiredSvcOptionId = 0 AND svcMap.PresentSvcOptionId <> svc.DisabledSvcOptionId)
OR
(svcMap.DesiredSvcOptionId <> 0 AND svcMap.DesiredSvcOptionId <> svc.DisabledSvcOptionId)
)
SOLUTION
This is the solution that I implemented and it gave me exactly what I needed when I cross checked it with LinqPad
from svcMap in db.ServicesMap
join svc in db.Services on svcMap.SvcId equals svc.SvcId
join option in db.Options on
((svcMap.DesiredSvcOptionId != 0 && svcMap.DesiredSvcOptionId != svc.DisabledSvcOptionId)
? svcMap.DesiredSvcOptionId
: (svcMap.PresentSvcOptionId != svc.DisabledSvcOptionId)
? svcMap.PresentSvcOptionId
: 0)
equals option.SvcOptionId
where svcMap.ToBill == 1
&& (
(svcMap.DesiredSvcOptionId == 0 &&
svcMap.PresentSvcOptionId != svc.DisabledSvcOptionId)
||
(svcMap.DesiredSvcOptionId != 0 &&
svcMap.DesiredSvcOptionId != svc.DisabledSvcOptionId)
)
select
new
{
svc.SvcName,
option.SvcOptionName,
svcMap.Price.GetValueOrDefault()
}

Why have a CASE in your joining criteria? What do you expect the optimizer to do with that exactly?
Here's a literal translation.
from svcMap in db.svcMaps
where svcMap.ToBill == 1
let svc = svcMap.Svc
where (svcMap.Desired == 0 && svcMap.Present <> svc.Disabled)
|| (svcMap.Desired <> 0 && svcMap.Desired <> svc.Disabled)
let optionId =
svcMap.Desired <> 0 && svcMap.Desired <> svc.Disabled ? svcMap.Desired :
svcMap.Present <> svc.Disabled ? svc.Present :
0
from option in db.Options
where option.SvcOptionId == optionId
select new {svc.SvcName, option.SvcOptionName, svcMap.Price }

Related

How to get the sum of the same column with different status

How can i add the same column with different status in a raw query laravel
$result = $this->sales_on_hand->where(function($query) use($request, $dateStart, $dateStart2){
$query->whereBetween('sales_onhands.created_at', [$dateStart, $dateStart2]);
if($request->has('branch') && $request->branch != ""){
$query->where('branch_id', $request->branch);
}
})->join('sales_onhand_deposits','sales_onhands.id','=','sales_onhand_deposits.sales_onhand_id'
)->select(
DB::raw(
'
IFNULL(SUM(sales_onhands.cash_on_hand), 0) AS cash_onhands,
IFNULL(SUM(sales_onhands.gc_onhand), 0) AS gc_onhands,
**IFNULL(SUM(sales_onhand_deposits.total), 0) AS total_pending_deposit where sales_onhand_deposits.is_verified = 0
IFNULL(SUM(sales_onhand_deposits.total), 0) AS total_approve_deposit where sales_onhand_deposits.is_verified = 1**
'
)
)->get();
You can use CASE statements in your sum()
DB::raw(
'
IFNULL(SUM(sales_onhands.cash_on_hand), 0) AS cash_onhands,
IFNULL(SUM(sales_onhands.gc_onhand), 0) AS gc_onhands,
IFNULL(SUM(case when sales_onhand_deposits.is_verified = 0 then sales_onhand_deposits.total else 0 end), 0) AS total_pending_deposit
IFNULL(SUM(case when sales_onhand_deposits.is_verified = 1 then sales_onhand_deposits.total else 0 end), 0) AS total_approve_deposit
'
)

LINQ Query condition based on a condition

I have a LINQ query as follows:
var query = from r in Context.Role()
join rg in Context.RoleGroup() on r.RoleId equals rg.FkRoleId
where r.RoleName != "guests" && r.RoleName != "SystemAdmin"
select rg;
However, I need an additional condition to include, that SystemAdmin should not be excluded based on external condition (say, the logged in user is superuser).
As suggested here, I modified the query like below:
var query = from r in Context.Role()
join rg in Context.RoleGroup() on r.RoleId equals rg.FkRoleId
where r.RoleName != "guests" && (userId == 1 || r.RoleName != "SystemAdmin")
select rg;
But I still can see SystemAdmin role in the output even if the userId is not 1. How can I get the desired output?
Use this code for dynamic where condition:
if (printType == "BatchWise")
{
whereCondition = "BatchNo.Equals(#" + 0 + ")";
array[0] = Convert.ToString(printNumber);
}
else
{
whereCondition = "TagNo.Equals(#" + 0 + ")";
array[0] = Convert.ToString(printNumber);
}
using (var inventoryDb = new InventoryDb())
{
var pricingInfo = (from price in invDb.Pricing.AsNoTracking()
where tagDtl.AvailableQuantity > 0
select new
{
PricingNo = price.PricingNo,
............
}).Where(whereCondition, array).ToList();
}
The query goes as follows:
var query = from r in Context.Role()
join rg in Context.RoleGroup() on r.RoleId equals rg.FkRoleId
where r.RoleName != "guests" && (userId == 1 || (userId> 1 && r.RoleName != "SystemAdmin"))
select rg;

LINQ to Entities grouped logical operations in Where

I'm trying to execute the following linq query and it seems to be ignoring order of operations. (Parentheses first)
var result = _repo.Transactions.Where(t =>
t.DateEntered > EntityFunctions.AddDays(DateTime.Now, -7)
&& ( t.TranDesc != "BALANCE FORWARD" && t.Withdrawl == 0 && t.Deposit == 0 ) );
Here's the where clause that generates:
WHERE ([Extent1].[dateentered] > (DATEADD (day, -7, SysDateTime())))
AND (N'BALANCE FORWARD' <> [Extent1].[TranDesc])
AND (cast(0 as decimal(18)) = [Extent1].[Withdrawl])
AND (cast(0 as decimal(18)) = [Extent1].[Deposit])
Any ideas what I'm doing wrong?
EDIT:
This is actually what I wanted and it solved my problem. Just didn't think it all the way though. Thanks.
var result = _repo.Transactions.Where(t =>
t.dateentered > EntityFunctions.AddDays(DateTime.Now, -7)
&& ((t.TranDesc == "BALANCE FORWARD" && (t.Withdrawl != 0 || t.Deposit != 0))
|| (t.TranDesc != "BALANCE FORWARD")));
There is no difference between a && (b && c && d) and a && b && c && d, and that's why parentheses within generated SQL are not exactly the same as in your LINQ query. But at the end there is no difference between these queries.

Linq to nHibernate - exclude elements without child elements

var locations = (from location in session.Query<Location>()
where
(location.MB_ID == 0 || location.MB_ID == null) &&
(location.hide != "Y" || location.hide == null) &&
(location.locationNameRaw != "" && location.locationNameRaw != null) &&
((location.isIPCapableText != "" && location.isIPCapableText != null) || (
(location.ISDNNumber1 != null && location.ISDNNumber1 != "") ||
(location.ISDNNumber2 != null && location.ISDNNumber2 != "") ||
(location.ISDNNumber3 != null && location.ISDNNumber3 != "") ||
(location.ISDNNumber4 != null && location.ISDNNumber4 != "") ||
(location.ISDNNumber5 != null && location.ISDNNumber5 != "") ||
(location.ISDNNumber6 != null && location.ISDNNumber6 != "")
))
&& (location.privateRoom == "N" || location.privateRoom == "" || location.privateRoom != null)
&& (
from lll in session.Query<LocationLonLat>()
where
location.locationID == lll.locationId
select lll.locationId
).Any()
&& (location.LastUpdatedTime > lastUpdateTime)
&& location.LocationTimes.Count() > 0
/*&& (
from lt in session.Query<LocationTimes>()
where
location.locationID == lt.LID
select lt.LID
).Any()*/
select location
)
.ToList();
There is a relationship between Location (1) and LocationTimes (many), and I only want to return a dataset of locations that have at least one LocationTime record.
I tried a couple of things...
When I add the line:
&& location.LocationTimes.Count() > 0
or if I add the line:
&& (
from lt in session.Query<LocationTimes>()
where
location.locationID == lt.LID
select lt.LID
).Any()
The underlying connection was closed: A connection that was expected to be kept alive was closed by the server.
I suspect that this may because of the size of the dataset or something...
Is there a better way of doing this? Like with a 'left outer join' or something?
I think a simple join should do it.
from locationTime in Query<LocationTime>()
join location in Query<Location>() on locationTime.Location.LocationId equals location.LocationId
join locationLat in Query<LocationLat>() on location.LocationLat.LocationLatId equals locationLat.LocationLatId
where ...
select location;

help with linq query

i am trying to get some data, but i dont know how can i do a if in linq, this is how i am trying to do
from so in db.Operations
where ((opType!= "0" ? so.Operation == int.Parse(opType) : false)
&& (idState!=0 ? so.State == idState : false)
&& (start != null ? so.StartDate == start : false)
&& (end !=null ? so.EndDate == end : false))
select so
the optype is a Int,
the idState is a Int,
end is a datetime,
start is a datime
what i am trying to do is, if those aren't null they add to the query function, so i can get all data together
for example: in c# code
if((opType!= "0")
where (so.Operation == int.Parse(opType)
if(idState!=0)
where (so.Operation == int.Parse(opType) && so.State == idState
.......
so if that isn't null, that sentence in that sql query (the TRUE part, i dont want to use the false part), add it to the where, so i can search all parameters that aren't null or 0
Since you're &&'ing them, looks like you want : true instead of : false.
Well not sure what you want exactly but here is a try:
var query = db.Operations.AsQueryable();
if (opType != null && opType != "0")
query = query.Where(x => x.Operation == int.Parse(opType);
if (idState != 0)
query = query.Where(x => x.State == idState);
if (start != null) // assuming that start is of type DateTime? otherwise use DateTime.MinValue
query = query.Where(x => x.StartDate.Date == start); // maybe >= is more appropriate
if (end != null) // also DateTime? assumed
query = query.Where(x => x.EndDate.Date == end); // maybe <= is more appropriate
var result = query.ToList(); // e.g. could also do an foreach, depending what you want to do
The trick in this approach is to build up the query successively. The query will not be enumerated until .ToList() or foreach is used to enumerate the list.
Actually this should yield the same:
from so in db.Operations
where ((opType != null && opType!= "0" ? so.Operation == int.Parse(opType) : true)
&& (idState!=0 ? so.State == idState : true)
&& (start != null ? so.StartDate.Date == start : true)
&& (end !=null ? so.EndDate.Date == end : true))
select so
opType!= "0" ? so.Operation == int.Parse(opType) : false
you should not use so.operation == int.parse.... instead use so.operation = int.Parse(opType)
You can use conditional parameters.
Change:
where ((opType!= "0" ? so.Operation == int.Parse(opType) : false)
To:
where ((opType!= "0" ? so.Operation == int.Parse(opType) : so.Operation == Operation)
and so on...

Resources