Incorrect output from stored procedure - sql-server

I am using below stored procedure to generate a crystal report.My report mainly filters data based on two possible values, Arcade or Franchise.
I filter data as Arcade = 1 , Franchise = 2 and Both = 0.The OutletType parameter get these int values.
When I filter for one particular value It gives me both arcade and franchise values.
ALTER PROCEDURE [dbo].[PrintReceiptCancellationWorkflow]
#EntryType int,
#OutletType int,
#RequestedUser varchar(50),
#FromDate DateTime2,
#ToDate DateTime2,
#OutletCode varchar(10),
#CancelledUser varchar(20),
#Status int
AS
BEGIN
SELECT
Outlets.OutletDesc AS 'Branch',
Receipt.CancelUser AS 'RequestedBy',
Receipt.RecDate AS 'ReqDateTime',
--ReceiptCancellationStatus.ApprovedStatus AS 'Status',
ReceiptCancellationStatus.StatusDesc As Status,
WorkflowRequestQueue.CposReference AS 'WCRNo',
Receipt.ReceiptNo AS 'ReceiptNo',
Receipt.PaymentMode AS 'PaymentMode',
Receipt.AppliedAmount AS 'Amount',
WorkflowRequestQueue.AppRejUser AS 'CompletedBy',
WorkflowRequestQueue.AppRejDateTime AS 'CompletedDateTime',
EntryTypes.EntryType AS 'PaymentCategory',
WorkflowRequestQueue.AppRejComment AS 'Comment',
OutletCategories.CatDesc As 'OutletType'
FROM Receipt
INNER JOIN
Outlets ON Receipt.OutletCode = Outlets.OutletCode
LEFT OUTER JOIN
EntryTypes ON Receipt.EntryTypeId = EntryTypes.Id
LEFT OUTER JOIN
WorkflowRequestQueue ON Receipt.CposReference = WorkflowRequestQueue.CposReference
LEFT OUTER JOIN
OutletCategories ON Outlets.OutletType = OutletCategories.CatCode
LEFT OUTER JOIN
ReceiptCancellationStatus ON WorkflowRequestQueue.ApprovedStatus = ReceiptCancellationStatus.Id
WHERE (Outlets.OutletType = #OutletType OR Outlets.OutletType = 0) OR
(Receipt.EntryTypeId = #EntryType OR Receipt.EntryTypeId = 0) OR
Receipt.CancelUser = #RequestedUser OR
(( CONVERT(DATE,WorkflowRequestQueue.AppRejDateTime) >= #FromDate) AND ( CONVERT(DATE,WorkflowRequestQueue.AppRejDateTime) <= #ToDate)) OR
Outlets.OutletCode = #OutletCode OR
WorkflowRequestQueue.ApprovedPerson = #CancelledUser OR
(WorkflowRequestQueue.ApprovedStatus = #Status OR WorkflowRequestQueue.ApprovedStatus = 0)
END
Outlet type drop down values,
$scope.VendorDropdown = [
{ "text": "Select", "value": "0" },
{ "text": "Arcade", "value": "1" },
{ "text": "Franchise", "value": "2" },
];
Report generation code,
object paymentCategory = Convert.ToInt32(Request.Form["PaymentCategory"]);
object vendor = Convert.ToInt32(Request.Form["Vendor"]);
object requestedUser = Convert.ToString(Request.Form["RequestedUser"]);
object cancelledUser = Convert.ToString(Request.Form["CancelledUser"]);
object Fromdate = Convert.ToDateTime(Request.Form["dateFrom"]);
object Todate = Convert.ToDateTime(Request.Form["dateTo"]);
object status = Convert.ToInt32(Request.Form["Status"]);
object outlet = Convert.ToString(Request.Form["Outlet"]);
if (isExcel)
{
myReport.Load(Server.MapPath("~/CPOSReport/MIS/CancellationReports/ReceiptCancellationWorkFlow.rpt"));
}
else {
myReport.Load(Server.MapPath("~/CPOSReport/MIS/CancellationReports/ReceiptCancellationWorkFlow.rpt"));
}
myReport.SetParameterValue("#EntryType", paymentCategory);
myReport.SetParameterValue("#OutletType",vendor );
myReport.SetParameterValue("#RequestedUser", requestedUser);
myReport.SetParameterValue("#CancelledUser", cancelledUser);
myReport.SetParameterValue("#FromDate", Fromdate);
myReport.SetParameterValue("#ToDate", Todate);
myReport.SetParameterValue("#Status", status);
myReport.SetParameterValue("#OutletCode", outlet);

All of your where conditions are OR'ed. This means that if one of them are satisfied, the row will be included.
You should probably try this WHERE in stead with the different conditions AND'ed together:
WHERE (Outlets.OutletType = #OutletType OR Outlets.OutletType = 0) AND
(Receipt.EntryTypeId = #EntryType OR Receipt.EntryTypeId = 0) AND
Receipt.CancelUser = #RequestedUser AND
(
( CONVERT(DATE,WorkflowRequestQueue.AppRejDateTime) >= #FromDate) AND
( CONVERT(DATE,WorkflowRequestQueue.AppRejDateTime) <= #ToDate)
) AND
Outlets.OutletCode = #OutletCode AND
WorkflowRequestQueue.ApprovedPerson = #CancelledUser AND
(WorkflowRequestQueue.ApprovedStatus = #Status OR WorkflowRequestQueue.ApprovedStatus = 0)

Related

Salesforce REST API Create an order class with Wrapper Not working

anyone can solve this issue as im getting Error - Method does not exist or incorrect signature: void productMAp(String) from the type CreateOrders
Order ord = new Order(
AccountId = oderWrap.AccountId,
EffectiveDate = EffectiveDate,
Status = oderWrap.Status,
PriceBook2Id = PricebookList[0].id,
contractid = contractMap.get(oderWrap.AccountId).id,
ShippingStreet = contractMap.get(oderWrap.AccountId).Account.ShippingStreet,
ShippingCity = contractMap.get(oderWrap.AccountId).Account.ShippingCity,
ShippingpostalCode = contractMap.get(oderWrap.AccountId).Account.ShippingpostalCode,
ShippingCountry = contractMap.get(oderWrap.AccountId).Account.ShippingCountry,
ShippingState = contractMap.get(oderWrap.AccountId).Account.ShippingState
);
for(OrderWrapper.OrderLineItems oderLineItem : oderWrap.OrderLineItems){
product2 pro = productMAp(oderLineItem.LineItemCode);
PricebookEntry pbe = PricebookEntryMAp(pro.id);
OrderItemList.add(createOrderLineItimes(ord,integer.valueof(oderLineItem.Quantity),pro,pbe));
}
if(ord!=null){
insert ord ;
for(OrderItem poLine : OrderItemList) {
poLine.orderid =poLine.order.Id;
}
insert OrderItemList;
}
Hard to say, what's the type of "productMap"?
Did you mean to use productMap.get(oderLineItem.LineItemCode)?

Does the left join order matter in linq query (EF Core 2)?

I have book table which has a relationship with three tables UserFavorites, UserRates, DiscountItems and last one (DiscountItems) has a relationship with Discounts table so I want to load discount with book if it exist
When create linq left join query with this order (join userfavoirtes then discountitems then discount then userate) generated SQL code is fine as expected
But when change order like below (join userfavoirtes then userate then discountitems then discount) generated query only contain first two join only
var books = (from b in result
join uf in UnitOfWork.Context.UserFavorites
on new { b.Id, RelatedType = RelatedTypeEnum.Book, UserId = userId }
equals new { Id = uf.RelatedId, uf.RelatedType, uf.UserId } into buf
from f in buf.DefaultIfEmpty()
join di in UnitOfWork.Context.DiscountItems
on b.Id equals di.BookId into bdi
from di in bdi.DefaultIfEmpty()
join d in UnitOfWork.Context.Discounts
on (di != null ? di.DiscountId : 0) equals d.Id into bd
from d in bd.DefaultIfEmpty()
join ur in UnitOfWork.Context.UserRates
on new { b.Id, UserId = userId }
equals new { Id = ur.BookId, UserId = ur.CreatedBy } into bur
from r in bur.DefaultIfEmpty()
select new BookViewModel
{
Id = b.Id,
Title = b.Title,
Price = b.Price,
BookImage = SetDefaultImageIfNoImage(b.BookImage),
IsFavorite = f != null ? f.IsFavorite : false,
Rate = bur.Any() ? Math.Round(bur.Average(a => a.Value), 1) : 0,
Discount = d
})
.OrderBy(a => a.CategoryId)
.ThenBy(a => a.Authors)
.Take(10).ToList();
this is generated sql query
SELECT *FROM [Book] AS [a]
LEFT JOIN [UserFavorites] AS [uf] ON (([a].[Id] = [uf].[RelatedId]) AND (3 = [uf].[RelatedType])) AND [uf].[UserId] IS NULL
LEFT JOIN [DiscountItems] AS [di] ON [a].[Id] = [di].[BookId]
LEFT JOIN [Discounts] AS [d] ON CASE
WHEN [di].[Id] IS NOT NULL
THEN [di].[DiscountId] ELSE 0
END = [d].[Id]
LEFT JOIN [UserRates] AS [ur] ON ([a].[Id] = [ur].[BookId]) AND [ur].[CreatedBy] IS NULL
WHERE ((([a].[Active] = 1) AND ([a].[Id] <> 62)) AND ([a].[Status] = 1))
but when write join with this order
var books = (from b in result
join uf in UnitOfWork.Context.UserFavorites
on new { b.Id, RelatedType = RelatedTypeEnum.Book, UserId = userId }
equals new { Id = uf.RelatedId, uf.RelatedType, uf.UserId } into buf
from f in buf.DefaultIfEmpty()
join ur in UnitOfWork.Context.UserRates
on new { b.Id, UserId = userId }
equals new { Id = ur.BookId, UserId = ur.CreatedBy } into bur
from r in bur.DefaultIfEmpty()
join di in UnitOfWork.Context.DiscountItems
on b.Id equals di.BookId into bdi
from di in bdi.DefaultIfEmpty()
join d in UnitOfWork.Context.Discounts
on (di != null ? di.DiscountId : 0) equals d.Id into bd
from d in bd.DefaultIfEmpty()
select new BookViewModel
{
Id = b.Id,
Title = b.Title,
Price = b.Price,
BookImage = SetDefaultImageIfNoImage(b.BookImage),
IsFavorite = f != null ? f.IsFavorite : false,
Rate = bur.Any() ? Math.Round(bur.Average(a => a.Value), 1) : 0,
Discount = d
})
.OrderBy(a => a.CategoryId)
.ThenBy(a => a.Authors)
.Take(10).ToList();
generated SQL query contains only the first two joins
SELECT *
FROM [Book] AS [a]
LEFT JOIN [UserFavorites] AS [uf] ON (([a].[Id] = [uf].[RelatedId]) AND (3 = [uf].[RelatedType])) AND [uf].[UserId] IS NULL
LEFT JOIN [UserRates] AS [ur] ON ([a].[Id] = [ur].[BookId]) AND [ur].[CreatedBy] IS NULL
WHERE ((([a].[Active] = 1) AND ([a].[Id] <> 62)))

Need to convert sql statement into Entity Framework equivalent

Given the following tables:
InstrumentLogs
InstrumentLogId (PK, int, not null)
InstrumentId (FK, int, not null)
LogDate (datetime, not null)
Action (string, not null)
Instruments
InstrumentId (PK, int, not null)
CountyId (FK, int, not null)
Counties
CountyId (PK, int, not null)
StateFips (FK, int, not null)
Name (string, not null)
States
StateFips (PK, int, not null)
Name (string, not null)
I need to figure out how to write this SQL query using Entity Framework:
select s.StateName, count(*) as total
from instruments as i
join counties as c on i.CountyID = c.CountyID
join states as s on s.StateFIPS = c.StateFIPS
where i.InstrumentID in
(select i1.InstrumentId from InstrumentLogs as i1 where i1.action = 'review' and
i1.logdate in (select max(logdate) from instrumentlogs as i2 where i1.instrumentid
=i2.InstrumentID group by i2.instrumentid))
group by s.StateName
I tried something along the lines of:
_context.Instruments.Include(i => i.County.State)
.Where(i => _context.Logs.Where(l => l.Action == 'review'
&& _context.Logs.Where(l2 => l2.InstrumentId == l.InstrumentId).Max(l2 => l2.LogDate) == l.LogDate).GroupBy(i => i.County.State.Name)
.Select(g => new { State = g.Key.Name, Total = g.Count() });
However, EF doesn't like this. I wind up with the error stating that only primitive types or enumeration types are supported.
Thanks for your help.
I finally got it to work like this
var _query = _dataContext.IndexLogs.GroupBy(l => l.InstrumentId, l => l)
.Select(grp => new { Id = grp.Key, Date = grp.Max(g => g.ActionDate) });
//Prequery to find log records that match given type and action type
var _indexes = _dataContext.IndexLogs.Where(l => l.Action == type
&& _query.Contains(new { Id = l.InstrumentId, Date = l.ActionDate})).Select(i => i.InstrumentId);
var _states = _dataContext.AdvancedIndexes
.Include(i => i.County.State)
.Where(a => a.Id > 0 && _indexes.Contains(a.Id))
.GroupBy(i => new { i.County.State.Id, i.County.State.Name })
.Select(g => new { fips = g.Key.Id, name = g.Key.Name, count = g.Count() });

Query Slow in Linq, Fast in LinqPad, SQL Management Studio and SQL Profiler

I have this linq query i'm using and it's taking 50 seconds to run when i am running it my asp.net application, however the same query executes in 500ms in LinqPad and Sql Management Studio.
I even took the query from the SQL Profiler and ran it again in SQL Management Studio and it takes around 500ms. What overhead Linq could be doing, that an extra 49s??
Below is the code for reference, thanks for your help.
var rCampaign =
(from a in db.AdCreative
join h in db.AdHit on a.ID equals h.AdID into gh
join l in db.AdGroup_Location on a.AdGroupID equals l.AdGroupID into gj
from subloc in gj.DefaultIfEmpty()
from subhits in gh.DefaultIfEmpty()
where a.AdGroup.AdHost.Select(q => q.ID).Contains(rPlatform.ID) &&
a.AdGroup.AdPublisher.Select(q => q.ID).Contains(rPublisher.ID) &&
a.AdDimensionID == AdSize &&
a.AdGroup.Campaign.Starts <= rNow &&
a.AdGroup.Campaign.Ends >= rNow &&
subhits.HitType == 1 &&
(subloc == null || subloc.LocationID == rLocationID)
select new {
ID = a.ID,
Name = a.Name,
Spent = (subhits.AdDimension != null) ? ((double)subhits.AdDimension.Credit / 1000) : 0,
CampaignID = a.AdGroup.Campaign.ID,
CampaignName = a.AdGroup.Campaign.Name,
CampaignBudget = a.AdGroup.Campaign.DailyBudget
}).GroupBy(adgroup => adgroup.ID)
.Select(adgroup => new {
ID = adgroup.Key,
Name = adgroup.FirstOrDefault().Name,
Spent = adgroup.Sum(q => q.Spent),
CampaignID = adgroup.FirstOrDefault().CampaignID,
CampaignName = adgroup.FirstOrDefault().CampaignName,
CampaignBudget = adgroup.FirstOrDefault().CampaignBudget,
})
.GroupBy(q => q.CampaignID)
.Select(campaigngroup => new {
CampaignID = campaigngroup.Key,
DailyBudget = campaigngroup.FirstOrDefault().CampaignBudget,
Consumed = campaigngroup.Sum(q => q.Spent),
RemainningCredit = campaigngroup.FirstOrDefault().CampaignBudget - campaigngroup.Sum(q => q.Spent),
Ads = campaigngroup.Select(ag => new {
ID = ag.ID,
Name = ag.Name,
Spent = ag.Spent
}).OrderBy(q => q.Spent)
})
.Where(q => q.Consumed <= q.DailyBudget).OrderByDescending(q => q.RemainningCredit).First();
There are a few ways you can simplify that query:
select into lets you keep it all in query syntax.
The join ... into/from/DefaultIfMany constructs implementing left joins can be replaced with join ... into construcs representing group joins.
Some of the groups near the end cannot be empty, so FirstOrDefault is unnecessary.
Some of the where conditions can be moved up to the top before the query gets complicated.
Here's the stab I took at it. The revisions were significant, so it might need a little debugging:
var rCampaign = (
from a in db.AdCreative
where a.AdDimensionID == AdSize &&
a.AdGroup.Campaign.Starts <= rNow &&
a.AdGroup.Campaign.Ends >= rNow &&
a.AdGroup.AdHost.Select(q => q.ID).Contains(rPlatform.ID) &&
a.AdGroup.AdPublisher.Select(q => q.ID).Contains(rPublisher.ID)
join hit in db.AdHit.Where(h => h.HitType == 1 && h.LocationID == rLocationID)
on a.ID equals hit.AdID
into hits
join loc in db.AdGroup_Location
on a.AdGroupID equals loc.AdGroupID
into locs
where !locs.Any() || locs.Any(l => l.LocationID == rLocationID)
select new {
a.ID,
a.Name,
Spent = hits.Sum(h => h.AdDimension.Credit / 1000) ?? 0,
CampaignID = a.AdGroup.Campaign.ID,
CampaignName = a.AdGroup.Campaign.Name,
CampaignBudget = a.AdGroup.Campaign.DailyBudget,
} into adgroup
group adgroup by adgroup.CampaignID into campaigngroup
select new
{
CampaignID = campaigngroup.Key,
DailyBudget = campaigngroup.First().CampaignBudget,
Consumed = campaigngroup.Sum(q => q.Spent),
RemainingCredit = campaigngroup.First().CampaignBudget - campaigngroup.Sum(q => q.Spent),
Ads = campaigngroup.Select(ag => new {
ag.ID,
ag.Name,
ag.Spent,
}).OrderBy(q => q.Spent)
} into q
where q.Consumed <= q.DailyBudget
orderby q.RemainingCredit desc)
.First()
I refactored using Query syntax (Not sure if it improved readability). Removed one group by. Made some minor adjustments (replaced FirstOrDefault with Key property, changed Contains to Any). Hopefully it has some effect of speed.
var rCampaign = (from cg in
(from a in db.AdCreative
from subhits in db.AdHit.Where(h => a.ID == h.AdID)
.DefaultIfEmpty()
from subloc in db.AdGroup_Location.Where(l => a.AdGroupID == l.AdGroupID)
.DefaultIfEmpty()
where a.AdGroup.AdHost.Any(q => q.ID == rPlatform.ID) &&
a.AdGroup.AdPublisher.Any(q => q.ID == rPublisher.ID) &&
a.AdDimensionID == AdSize &&
a.AdGroup.Campaign.Starts <= rNow &&
a.AdGroup.Campaign.Ends >= rNow &&
subhits.HitType == 1 &&
(subloc == null || subloc.LocationID == rLocationID)
group new { a, subhits } by new { ID = a.ID, a.Name, CampaignID = a.AdGroup.Campaign.ID, CampaignName = a.AdGroup.Campaign.Name, CampaignBudget = a.AdGroup.Campaign.DailyBudget } into g
select new
{
ID = g.Key.ID,
Name = g.Key.Name,
Spent = g.Sum(x => (x.subhits.AdDimension != null) ? ((double)subhits.AdDimension.Credit / 1000) : 0),
CampaignID = g.Key.CampaignID,
CampaignName = g.Key.CampaignName,
CampaignBudget = g.Key.CampaignBudget
})
group cg by new { cg.CampaignID, cg.CampaignBudget } into cg
let tempConsumed = cg.Sum(q => q.Spent)
let tempRemainningCredit = cg.Key.CampaignBudget - tempConsumed
where tempConsumed <= cg.Key.CampaignBudget
orderby tempRemainningCredit desc
select new
{
CampaignID = cg.Key.CampaignID,
DailyBudget = cg.Key.CampaignBudget,
Consumed = tempConsumed,
RemainningCredit = tempRemainningCredit,
Ads = from ag in cg
orderby ag.Spent
select new
{
ID = ag.ID,
Name = ag.Name,
Spent = ag.Spent
}
}).First();

LINQ orderby int array index value

Using LINQ I would like to sort by the passed in int arrays index.
So in the code below attribueIds is my int array. I'm using the integers in that array for the where clause but I would like the results in the order that they were in while in the array.
public List BuildTable(int[] attributeIds)
{
using (var dc = new MyDC())
{
var ordering = attributeIds.ToList();
var query = from att in dc.DC.Ecs_TblAttributes
where attributeIds.Contains(att.ID)
orderby(ordering.IndexOf(att.ID))
select new Common.Models.Attribute
{
AttributeId = att.ID,
DisplayName = att.DisplayName,
AttributeName = att.Name
};
return query.ToList();
}
}
I would recommend selecting from the attributeIDs array instead. This will ensure that your items will be correctly ordered without requiring a sort.
The code should go something like this:
var query =
from id in attributeIds
let att = dc.DC.Ecs_TblAttributes.FirstOrDefault(a => a.ID == id)
where att != null
select new Common.Models.Attribute
{
AttributeId = att.ID,
DisplayName = att.DisplayName,
AttributeName = att.Name
};
Why don't you join:
public List BuildTable(int[] attributeIds)
{
using (var dc = new MyDC())
{
var query = from attID in attributeIds
join att in dc.DC.Ecs_TblAttributes
on attID equals att.ID
select new Common.Models.Attribute
{
AttributeId = attID,
DisplayName = att.DisplayName,
AttributeName = att.Name
};
return query.ToList();
}
}

Resources