Pagination on DevExtreme dxDataGrid with Skip / Take loadOptions - devexpress

We have a table with a large amount of data and I do not want to load it at once for my dxDataGrid.
I want to implement paging with Skip / Take which is supplied from the dxDataGrid's DataSourceLoadOptions.
This is my controller:
[HttpGet]
public async Task<Object> GetSalesOrdersWithTotals(DataSourceLoadOptions loadOptions)
{
try
{
var results = await SalesOrderService.GetSalesOrdersWithTotals(loadOptions.Skip, loadOptions.Take, 40);
loadOptions.Skip = 0;
loadOptions.Take = 0;
return DataSourceLoader.Load(results, loadOptions);
}
catch (Exception ex)
{
return Json(new { code = "422", success = false, message = "Unable to fetch sales orders with totals - " + ex.ToString() });
}
}
This is the service that returns the data:
public async Task<IEnumerable<SalesOrderWithTotals>> GetSalesOrdersWithTotals(int skip, int take, int defaultPageSize)
{
if (take == 0)
{
//Fix for passing a 0 take
take = defaultPageSize;
}
var salesOrderWithTotals =
from o in _context.SalesOrder
select new SalesOrderWithTotals
{
SalesOrderId = o.SalesOrderId,
Net = _context.SalesOrderItem.Where(it => it.SalesOrderId == o.SalesOrderId).Select(it => it.Qty == null ? 0 : it.Qty.Value * it.UnitPrice == null ? 0 : it.UnitPrice.Value).Sum(),
Tax = _context.SalesOrderItem.Where(it => it.SalesOrderId == o.SalesOrderId).Select(it => it.Qty == null ? 0 : it.Qty.Value * it.UnitPrice == null ? 0 : it.UnitPrice.Value).Sum() * (o.Tax.Percentage /100),
Gross = _context.SalesOrderItem.Where(it => it.SalesOrderId == o.SalesOrderId).Select(it => it.Qty == null ? 0 : it.Qty.Value * it.UnitPrice == null ? 0 : it.UnitPrice.Value).Sum() + _context.SalesOrderItem.Where(it => it.SalesOrderId == o.SalesOrderId).Select(it => it.Qty == null ? 0 : it.Qty.Value * it.UnitPrice == null ? 0 : it.UnitPrice.Value).Sum() * (o.Tax.Percentage / 100),
Name = o.Customer.Name,
CustomerOrderNumber = o.CustomerOrderNumber,
Contact = o.Contact,
OrderDate = o.OrderDate
};
return await salesOrderWithTotals.Skip(skip).Take(take).ToListAsync();
}
Looking at SQL profiler, this takes the first 40 records but of course the dxDataGrid is not aware of the total count of records so pagination is not available.
What would be the best method to achieve what I want in this case?
Many thanks

You must do an extra query to get the count of your SalesOrder and keep it in for example salesOrderCount. Then keep the Load method return data as bellow.
LoadResult result = DataSourceLoader.Load(results, loadOptions);
LoadResult has a parameter called totalCount so set it with the real count of your data:
result.totalCount = salesOrderCount;
and then
return result;
Now the dxDataGrid is aware of the total count of records.

Related

Financial Dimension after save is empty

I have financial dimension which contact values like BuildingID and ContractID.
When new building is created, dimension is properly filled with data. But, after that there is need for contract creation.
When contract is created there is value in financial dimension field for contractID.
But, when contract is saved, financial dimension for contract id disappear. When I check in DIMENSIONATTRIBUTEVALUESET table value for that ContractID dimension is null, there is only value for BuildingID.
I have this method for init dimensions:
void initDimensions()
{
DimensionDefault dimension;
PMGOrgDimension orgDimension;
CompanyId companyId;
PMEGround ground;
PMEBuilding building;
switch(pmcContract.EstateType)
{
case PMCEstateType::Ground :
ground = PMEGround::find(pmcContract.EstateId);
dimension = PMEObjectLegalEntity::find(ground.TableId, ground.RecId).DefaultDimension;
orgDimension = ground.OrgDimension;
companyId = ground.CompanyId;
break;
case PMCEstateType::Building :
building = PMEBuilding::find(pmcContract.EstateId);
dimension = PMEObjectLegalEntity::find(building.TableId, building.RecId).DefaultDimension;
orgDimension = building.OrgDimension;
companyId = building.CompanyId;
break;
default :
dimension = pmcContract.DefaultDimension;
orgDimension = pmcContract.OrgDimension;
companyId = pmcContract.CompanyId;
break;
}
pmcContract.DefaultDimension = dimension;
pmcContract.OrgDimension = orgDimension;
pmcContract.CompanyId = companyId;
}
Is there something what I missing ?
Try changing this line:
pmcContract.DefaultDimension = dimension;
To this:
pmcContract.DefaultDimension = DimensionDefaultingService::serviceMergeDefaultDimensions(pmcContract.DefaultDimension, dimension);
Issue is in this method:
static server public DimensionDefault tableDimension(Common _c, DimensionDefault _d)
{
DimensionAttribute dimensionAttribute;
DimensionAttributeValue dimensionAttributeValue;
DimensionAttributeSetItem dimensionAttributeSetItem;
DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage;
DimensionDefault cDimensionDefault;
DimensionDefault ret;
;
ret = _d;
select firstonly RecId from dimensionAttribute
where dimensionAttribute.BackingEntityTableId == _c.TableId
join firstonly RecId from dimensionAttributeSetItem
where dimensionAttributeSetItem.DimensionAttributeSet == DimensionCache::getDimensionAttributeSetForLedger()
&& dimensionAttributeSetItem.DimensionAttribute == dimensionAttribute.RecId;
if (dimensionAttributeSetItem.RecId != 0)
{
dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimensionAttribute.RecId, _c.RecId, false, true);
if (dimensionAttributeValue.RecId != 0)
{
dimensionAttributeValueSetStorage = new DimensionAttributeValueSetStorage();
dimensionAttributeValueSetStorage.addItemValues(dimensionAttributeValue.DimensionAttribute, dimensionAttributeValue.RecId, dimensionAttributeValue.HashKey);
cDimensionDefault = dimensionAttributeValueSetStorage.save();
if (cDimensionDefault != 0)
{
ret = LedgerDimensionDefaultFacade::serviceMergeDefaultDimensions(cDimensionDefault, _d);
}
}
}
return ret;
}
Merge is not working. It only takes values for _d. Not merging them.

Datatables Object Reference not set to instance of an object for one variable

This is my datatables serverside implementation. FilterInput contains 5 variables:
Level <- string
Message <- string
Exception <-string
StartDate <- DateTime
EndDate <- DateTime
For some reason when I run this code as it is, I will always get this error:
{System.NullReferenceException: Object reference not set to an
instance of an object.
This is referring to this line:
data = data.Where(
u => u.Level.ToString().ToLower().Contains(FilterInput.Level.ToLower()) &&
u.Message.ToString().ToLower().Contains(FilterInput.Message.ToLower()) &&
u.Exception.ToString().ToLower().Contains(FilterInput.Exception.ToLower())
).ToList();
However, if I remove the search for FilterInput.Exception, everything runs fine again. I have tested it with input ("abc") or without input ("") and the results are the same. The other FilterInputs don't have the same error.
public JsonResult Search(SearchViewModels Input, EventLogsSearchViewModel FilterInput)
{
JsonResult result = new JsonResult(null);
try
{
var data = dbContext.EventLogs.ToList();
int totalRecords = data.Count;
var modelStructure = new Dictionary<int, string>();
modelStructure.Add(1, "Level");
modelStructure.Add(2, "TimeStamp");
modelStructure.Add(3, "LogEvent");
modelStructure.Add(4, "Message");
modelStructure.Add(5, "MessageTemplate");
modelStructure.Add(6, "Exception");
modelStructure.Add(7, "Properties");
var StartDate = FilterInput.StartDate != default(DateTime);
var EndDate = FilterInput.EndDate != default(DateTime);
if ((!string.IsNullOrEmpty(FilterInput.Level) && !string.IsNullOrWhiteSpace(FilterInput.Level)) ||
(!string.IsNullOrEmpty(FilterInput.Message) && !string.IsNullOrWhiteSpace(FilterInput.Message)) ||
(!string.IsNullOrEmpty(FilterInput.Exception) && !string.IsNullOrWhiteSpace(FilterInput.Exception)) ||
(StartDate && EndDate))
{
data = data.Where(
u => u.Level.ToString().ToLower().Contains(FilterInput.Level.ToLower()) &&
u.Message.ToString().ToLower().Contains(FilterInput.Message.ToLower()) &&
u.Exception.ToString().ToLower().Contains(FilterInput.Exception.ToLower())
).ToList();
data = data.Where(u => u.TimeStamp >= FilterInput.StartDate && u.TimeStamp <= FilterInput.EndDate).ToList();
}
if (!(string.IsNullOrEmpty(Input.Order) && string.IsNullOrEmpty(Input.OrderDir)))
{
var columnName = modelStructure.FirstOrDefault(f => f.Key == Convert.ToInt32(Input.Order));
data = data.AsQueryable().OrderBy(columnName.Value + " " + Input.OrderDir).ToList();
}
int recFilter = data.Count;
data = data.Skip(Input.StartRec).Take(Input.PageSize).ToList();
var modifiedData = data.Select(u => new EventLogsListViewModel
{
Id = u.Id,
Message = u.Message,
MessageTemplate = u.MessageTemplate,
Level = u.Level,
TimeStamp = u.TimeStamp,
Exception = u.Exception,
Properties = u.Properties,
LogEvent = u.LogEvent
});
result = this.Json(new
{
draw = Convert.ToInt32(Input.Draw),
recordsTotal = totalRecords,
recordsFiltered = recFilter,
data = modifiedData,
order = Input.Order,
orderdir = Input.OrderDir
});
}
catch (Exception e)
{
logger.LogError(e, LoggingGlobals.LoadingException);
}
return result;
}
EDIT: The exception still happens even when FilterInput.Exception is not null

Conditional to limit .Net webservice results

I'm not sure if this is the right way but I have a web service that returns json. Now I wanted to set a conditional to omit rows returned that have a value of false in cell appearInShowcase. Most of the code is pretty straight forward what it does but the cell that has a true false value is appearInShowcase which is in a table photo. In the ms sql database the appearInShowcase is of type ntext.
public List<wsGalleryPhotos> GetGalleryPhotos(int collectionID)
{
photoDataContext dc = new photoDataContext();
List<wsGalleryPhotos> results = new List<wsGalleryPhotos>();
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.GetCultureInfo("en-US");
foreach (photo photo in dc.photos.Where(s => s.collectionID == collectionID))
{
if(photo.appearInShowcase == "true")
{
results.Add(new wsGalleryPhotos()
{
photoID = photo.photoID,
collectionID = Convert.ToInt32(photo.collectionID),
name = photo.name,
description = photo.description,
filepath = photo.filepath,
thumbnail = photo.thumbnail
});
}
}
return results;
}
if you want to add a condition, you should do it like this:
public List<wsGalleryPhotos> GetGalleryPhotos(int collectionID)
{
photoDataContext dc = new photoDataContext();
List<wsGalleryPhotos> results = new List<wsGalleryPhotos>();
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.GetCultureInfo("en-US");
results = dc.photos.Where(s => s.collectionID == collectionID && s.appearInShowcase == "true")
.Select(s => new wsGalleryPhotos
{
photoID = s.photoID,
collectionID = collectionID,
name = s.name,
description = s.description,
filepath = s.filepath,
thumbnail = s.thumbnail
}).ToList();
return results;
}

Case Statements in LINQ query - AnonymousType to String?

I basically have the following:
public ActionResult Search(string searchString, string clientNo, int status = -1)
{
var statusLst = new List<string>();
var statusNoQry = from b in db.Briefs
orderby b.Status
select new
{
status = (
b.Status == 0 ? "Requested" :
b.Status == 1 ? "In Progress" :
"Undefined"
)
};
statusLst.AddRange(statusNoQry.Distinct()); <<--- ERROR HERE
ViewBag.status = new SelectList(statusLst);
var ClientNoLst = new List<string>();
var ClientNoQry = from b in db.Briefs
orderby b.Client_No_
where b.Client_Type == 0
select b.Client_No_;
ClientNoLst.AddRange(ClientNoQry.Distinct());
ViewBag.clientNo = new SelectList(ClientNoLst);
var briefs = from b in db.Briefs
select b;
Session["searchString"] = searchString;
Session["clientNo"] = clientNo;
if (!String.IsNullOrEmpty(searchString))
{
briefs = briefs.Where(s => s.Client_No_.Contains(searchString) || s.Name.Contains(searchString));
}
if ((status > -1) && (status < 10))
{
briefs = briefs.Where(y => y.Status == status);
}
if (string.IsNullOrEmpty(clientNo))
return View(briefs);
else
return View(briefs.Where(x => x.Client_No_ == clientNo));
}
However, I receive the following area:
Error 7 Argument 1: cannot convert from 'System.Linq.IQueryable<AnonymousType#1>' to 'System.Collections.Generic.IEnumerable<string>'
Status is of type int but I would like to cast it to string for my dropdownlist. I'm quite new to all this, what is the appropriate way of achieving this?
Your selector is returning an anonymous type:
select new
{
status = (
b.Status == 0 ? "Requested" :
b.Status == 1 ? "In Progress" :
"Undefined"
)
};
You need to return a set of strings though. The error is telling you exactly what the problem is.
select
(b.Status == 0 ? "Requested" :
b.Status == 1 ? "In Progress" :
"Undefined");
Edit - You didn't post the rest of the method, but from you have your also not disposing your context object, which can cause problems. Normally you wrap this in a using clause.

Actionscript 3 - Fastest way to parse yyyy-mm-dd hh:mm:ss to a Date object?

I have been trying to find a really fast way to parse yyyy-mm-dd [hh:mm:ss] into a Date object. Here are the 3 ways I have tried doing it and the times it takes each method to parse 50,000 date time strings.
Does anyone know any faster ways of doing this or tips to speed up the methods?
castMethod1 takes 3673 ms
castMethod2 takes 3812 ms
castMethod3 takes 3931 ms
Code:
private function castMethod1(dateString:String):Date {
if ( dateString == null ) {
return null;
}
var year:int = int(dateString.substr(0,4));
var month:int = int(dateString.substr(5,2))-1;
var day:int = int(dateString.substr(8,2));
if ( year == 0 && month == 0 && day == 0 ) {
return null;
}
if ( dateString.length == 10 ) {
return new Date(year, month, day);
}
var hour:int = int(dateString.substr(11,2));
var minute:int = int(dateString.substr(14,2));
var second:int = int(dateString.substr(17,2));
return new Date(year, month, day, hour, minute, second);
}
-
private function castMethod2(dateString:String):Date {
if ( dateString == null ) {
return null;
}
if ( dateString.indexOf("0000-00-00") != -1 ) {
return null;
}
dateString = dateString.split("-").join("/");
return new Date(Date.parse( dateString ));
}
-
private function castMethod3(dateString:String):Date {
if ( dateString == null ) {
return null;
}
var mainParts:Array = dateString.split(" ");
var dateParts:Array = mainParts[0].split("-");
if ( Number(dateParts[0])+Number(dateParts[1])+Number(dateParts[2]) == 0 ) {
return null;
}
return new Date( Date.parse( dateParts.join("/")+(mainParts[1]?" "+mainParts[1]:" ") ) );
}
No, Date.parse will not handle dashes by default. And I need to return null for date time strings like "0000-00-00".
I've been using the following snipplet to parse UTC date strings:
private function parseUTCDate( str : String ) : Date {
var matches : Array = str.match(/(\d\d\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)Z/);
var d : Date = new Date();
d.setUTCFullYear(int(matches[1]), int(matches[2]) - 1, int(matches[3]));
d.setUTCHours(int(matches[4]), int(matches[5]), int(matches[6]), 0);
return d;
}
Just remove the time part and it should work fine for your needs:
private function parseDate( str : String ) : Date {
var matches : Array = str.match(/(\d\d\d\d)-(\d\d)-(\d\d)/);
var d : Date = new Date();
d.setUTCFullYear(int(matches[1]), int(matches[2]) - 1, int(matches[3]));
return d;
}
No idea about the speed, I haven't been worried about that in my applications. 50K iterations in significantly less than a second on my machine.
This was the fastest I could come up with after some fiddling:
private function castMethod4(dateString:String):Date {
if ( dateString == null )
return null;
if ( dateString.length != 10 && dateString.length != 19)
return null;
dateString = dateString.replace("-", "/");
dateString = dateString.replace("-", "/");
return new Date(Date.parse( dateString ));
}
I get 50k iterations in about 470ms for castMethod2() on my computer and 300 ms for my version (that's the same amount of work done in 63% of the time). I'd definitely say both are "Good enough" unless you're parsing silly amounts of dates.
I'm guessing Date.Parse() doesn't work?
Well then method 2 seems the best way:
private function castMethod2(dateString:String):Date {
if ( dateString == null ) {
return null;
}
if ( dateString.indexOf("0000-00-00") != -1 ) {
return null;
}
dateString = dateString.split("-").join("/");
return new Date(Date.parse( dateString ));
}
Because Date.parse() does not accept all possible formats, we can preformat the passed dateString value using DateFormatter with formatString that Data.parse() can understand, e.g
// English formatter
var stringValue = "2010.10.06"
var dateCommonFormatter : DateFormatter = new DateFormatter();
dateCommonFormatter.formatString = "YYYY/MM/DD";
var formattedStringValue : String = dateCommonFormatter.format(stringValue);
var dateFromString : Date = new Date(Date.parse(formattedStringValue));
var strDate:String = "2013-01-24 01:02:40";
function dateParser(s:String):Date{
var regexp:RegExp = /(\d{4})\-(\d{1,2})\-(\d{1,2}) (\d{2})\:(\d{2})\:(\d{2})/;
var _result:Object = regexp.exec(s);
return new Date(
parseInt(_result[1]),
parseInt(_result[2])-1,
parseInt(_result[3]),
parseInt(_result[4]),
parseInt(_result[5]),
parseInt(_result[6])
);
}
var myDate:Date = dateParser(strDate);
Here is my implementation. Give this a try.
public static function dateToUtcTime(date:Date):String {
var tmp:Array = new Array();
var char:String;
var output:String = '';
// create format YYMMDDhhmmssZ
// ensure 2 digits are used for each format entry, so 0x00 suffuxed at each byte
tmp.push(date.secondsUTC);
tmp.push(date.minutesUTC);
tmp.push(date.hoursUTC);
tmp.push(date.getUTCDate());
tmp.push(date.getUTCMonth() + 1); // months 0-11
tmp.push(date.getUTCFullYear() % 100);
for(var i:int=0; i < 6/* 7 items pushed*/; ++i) {
char = String(tmp.pop());
trace("char: " + char);
if(char.length < 2)
output += "0";
output += char;
}
output += 'Z';
return output;
}

Resources