How can improve this Linq query expressions performance? - performance

public bool SaveValidTicketNos(string id,string[] ticketNos, string checkType, string checkMan)
{
bool result = false;
List<Carstartlistticket>enties=new List<Carstartlistticket>();
using (var context = new MiniSysDataContext())
{
try
{
foreach (var ticketNo in ticketNos)
{
Orderticket temp = context.Orderticket.ByTicketNo(ticketNo).SingleOrDefault();
if (temp != null)
{
Ticketline ticketline= temp.Ticketline;
string currencyType = temp.CurrencyType;
float personAllowance=GetPersonCountAllowance(context,ticketline, currencyType);
Carstartlistticket carstartlistticket = new Carstartlistticket()
{
CsltId = Guid.NewGuid().ToString(),
Carstartlist = new Carstartlist(){CslId = id},
LeaveDate = temp.LeaveDate,
OnPointName = temp.OnpointName,
OffPointName = temp.OffpointName,
OutTicketMan = temp.OutBy,
TicketNo = temp.TicketNo,
ChekMan = checkMan,
Type = string.IsNullOrEmpty(checkType)?(short?)null:Convert.ToInt16(checkType),
CreatedOn = DateTime.Now,
CreatedBy = checkMan,
NumbserAllowance = personAllowance
};
enties.Add(carstartlistticket);
}
}
context.BeginTransaction();
context.Carstartlistticket.InsertAllOnSubmit(enties);
context.SubmitChanges();
bool changeStateResult=ChangeTicketState(context, ticketNos,checkMan);
if(changeStateResult)
{
context.CommitTransaction();
result = true;
}
else
{
context.RollbackTransaction();
}
}
catch (Exception e)
{
LogHelper.WriteLog(string.Format("CarstartlistService.SaveValidTicketNos({0},{1},{2},{3})",id,ticketNos,checkType,checkMan),e);
context.RollbackTransaction();
}
}
return result;
}
My code is above. I doubt these code have terrible poor performance. The poor performance in the point
Orderticket temp = context.Orderticket.ByTicketNo(ticketNo).SingleOrDefault();
,actually, I got an string array through the method args,then I want to get all data by ticketNos from database, here i use a loop,I know if i write my code like that ,there will be cause performance problem and it will lead one more time database access,how can avoid this problem and improve the code performance,for example ,geting all data by only on databse access
I forget to tell you the ORM I use ,en ,the ORM is PlinqO based NHibernate
i am looking forward to having your every answer,thank you

using plain NHibernate
var tickets = session.QueryOver<OrderTicket>()
.WhereRestrictionOn(x => x.TicketNo).IsIn(ticketNos)
.List();
short? type = null;
short typeValue;
if (!string.IsNullOrEmpty(checkType) && short.TryParse(checkType, out typeValue))
type = typeValue;
var entitiesToSave = tickets.Select(ticket => new Carstartlistticket
{
CsltId = Guid.NewGuid().ToString(),
Carstartlist = new Carstartlist() { CslId = id },
LeaveDate = ticket.LeaveDate,
OnPointName = ticket.OnpointName,
OffPointName = ticket.OffpointName,
OutTicketMan = ticket.OutBy,
TicketNo = ticket.TicketNo,
ChekMan = checkMan,
CreatedOn = DateTime.Now,
CreatedBy = checkMan,
Type = type,
NumbserAllowance = GetPersonCountAllowance(context, ticket.Ticketline, ticket.CurrencyType)
});
foreach (var entity in entitiesToSave)
{
session.Save(entity);
}
to enhance this further try to preload all needed PersonCountAllowances

Related

XUnit Test for ViewComponent returns null result?

I am trying to test my ViewComponent with XUnit.
When I debug through the component and set a break point right before it returns the Component View, the model is set.
Here is the simple model I am returning.
public class IntDashMakeRecAssgnmntsPoRespMngrVM
{
public IEnumerable<Audit> Audits { get; set; }
}
And I am trying to assert the Audits.Count() is greater than 0.
Here is my View Component:
public class IntDashMakeRecAssgnmntsPoRespMngrViewComponent : ViewComponent
{
private IAuditRepository _auditRepo;
private IExternalRepository _externalRepo;
public IntDashMakeRecAssgnmntsPoRespMngrViewComponent(IAuditRepository auditRepo,
IExternalRepository externalRepo)
{
_auditRepo = auditRepo;
_externalRepo = externalRepo;
}
public IViewComponentResult Invoke()
{
ClaimsPrincipal user = HttpContext.Request.HttpContext.User;
short staffId = short.Parse(user.Claims.Single(c => c.Type == "StaffId").Value);
// Get all Internal Audits that are not closed and not completed
var audits = _auditRepo.Audits
.Include(a => a.Findings).ThenInclude(f => f.Recommendations).ThenInclude(r => r.Assignments)
.Where(a => a.StatusID != 3 && a.StatusID != 11);
var external = _externalRepo.ExternalRecords;
audits = audits.Where(a => !external.Any(e => e.AuditID == a.AuditID));
if (User.IsInRole("PAG_SPEC") && !User.IsInRole("PAG_ADMIN_INT"))
{
audits = audits.Where(a =>
a.Assignments.Any(assn => assn.AssignmentAuditId == a.AuditID
&& assn.AssignmentRoleId == 2 && assn.AssignmentStaffId == staffId));
}
// Where audit has a recommendation without an assigned PO Authorizer
// OR without an assigned Responsible Manager (Rec Level).
List<Audit> auditsToAssign = new List<Audit>();
foreach (Audit audit in audits)
{
foreach (Finding finding in audit.Findings)
{
foreach (Recommendation rec in finding.Recommendations)
{
if (!rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 15)
|| !rec.Assignments.Any(asgn => asgn.AssignmentRoleId == 26)
)
{
auditsToAssign.Add(rec.Finding.Audit);
break;
}
}
}
}
IntDashMakeRecAssgnmntsPoRespMngrVM intDashMakeRecAssgnmntsPoRespMngrVM =
new IntDashMakeRecAssgnmntsPoRespMngrVM
{
Audits = auditsToAssign
};
return View("/Views/InternalAudit/Components/Dashboard/IntDashMakeRecAssgnmntsPoRespMngr/Default.cshtml", intDashMakeRecAssgnmntsPoRespMngrVM);
}
}
When I get to this line in debugging and break to inspect, I have 1 Audit which I want:
return View("/Views/InternalAudit/Components/Dashboard/IntDashMakeRecAssgnmntsPoRespMngr/Default.cshtml", intDashMakeRecAssgnmntsPoRespMngrVM);
Now here is my Unit Test:
[Fact]
public void ReturnsAudit_1Finding_1Rec_1Asgn_PONeeded_RespMnrAssigned()
{
// Arrange
var audits = new Audit[]
{
new Audit { AuditID = 1 }
};
var findings = new Finding[]
{
new Finding{ Audit = audits[0], FindingId = 1 } // 1 Finding
};
var recommendations = new List<Recommendation>()
{
new Recommendation // 1 Rec
{
Finding = findings[0],
Assignments = new List<Assignment>()
{
// PO Authorizor
new Assignment { AssignmentRoleId = 15 }
// No Responsible Manager
}
}
};
audits[0].Findings = findings;
findings[0].Recommendations = recommendations;
Mock<IAuditRepository> mockAuditRepo = new Mock<IAuditRepository>();
mockAuditRepo.Setup(m => m.Audits).Returns(audits.AsQueryable());
Mock<IExternalRepository> mockExternalRepo = new Mock<IExternalRepository>();
mockExternalRepo.Setup(m => m.ExternalRecords).Returns(
new External[0].AsQueryable()
);
// Act
var component = new IntDashMakeRecAssgnmntsPoRespMngrViewComponent(
mockAuditRepo.Object, mockExternalRepo.Object);
component.ViewComponentContext = new ViewComponentContext();
component.ViewComponentContext.ViewContext.HttpContext = TestContext;
var result =
component.Invoke() as IntDashMakeRecAssgnmntsPoRespMngrVM;
int auditCount = (result).Audits.Count();
// Assert
Assert.Equal(1, auditCount);
}
Why is result null on this line?
var result =
component.Invoke() as IntDashMakeRecAssgnmntsPoRespMngrVM;
I also tried this first and it is still null:
ViewComponentResult result =
component.Invoke() as ViewComponentResult;
int auditCount =
((IntDashMakeRecAssgnmntsPoRespMngrVM)result.Model).Audits.Count();
I figured it out.
I wasn't casting the result to the right type.
I had this:
ViewComponentResult result =
component.Invoke() as ViewComponentResult;
int auditCount =
((IntDashMakeRecAssgnmntsPoRespMngrVM)result.Model).Audits.Count();
It should be this:
var result =
component.Invoke() as ViewViewComponentResult;
int auditCount =
((IntDashMakeRecAssgnmntsPoRespMngrVM)result.ViewData.Model).Audits.Count();
ViewViewComponentResult instead of ViewComponentResult.

Windows azure - the specified table not found

I'm trying to get the daa from windows azure storage but I'm getting table not found. I've already saw the others answers but nothing works...
I did try this:
private void popula()
{
var account = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("Conn"));
account.CreateCloudTableClient().CreateTableIfNotExist("fiscal");
var context = new CRUDManifestacoesEntities(account.TableEndpoint.ToString(), account.Credentials);
Hashtable ht = (Hashtable)ViewState["filtro"];
var teste = ViewState["x"].ToString();
if (ht == null)
GridView1.DataSource = context.SelectConc(teste);
else
GridView1.DataSource = context.SelectConc(ht);
}
public List<ManifestacaoGrid> SelectConc(string conc)
{
conc = Crypto.DecryptString(conc);
IQueryable<ManifestacaoEntity> results = null;
if (!conc.Equals("dfg"))
results = from c in ManifestacaoEntities where c.concessionaria == conc select c;
else
results = from c in ManifestacaoEntities select c;
var query = results.AsTableServiceQuery<ManifestacaoEntity>();
var queryResults = query.Execute();
List<ManifestacaoGrid> al = new List<ManifestacaoGrid>();
foreach (ManifestacaoEntity mf in queryResults)
{
.......
}
I'm getting this error:
TableNotFoundThe table specified does not exist.
RequestId:285f6ef7-b1ce-4c21-9406-3e9f6a58755b
Time:2014-01-15T14:30:55.7989535Z
EDIT: I did print '_account' to see if the credentials are correct:
var credencial = "Connection string with sensitive data: " + account.ToString(true);
and the AccountName and AccountKey are correct ...but how can I know if the requested table is correct?
The secundary key is needed in storage account?
I did found the problem. I write
public IQueryable<UserEntity> UserEntities
{
get
{
return this.CreateQuery<UserEntity>("tableName");
}
}
Instead of:
public IQueryable<UserEntity> UserEntities
{
get
{
return this.CreateQuery<UserEntity>("UserEntities");
}
}

The method 'OrderBy' must be called before the method 'Skip' Exception

I was trying to implement the jQgrid using MvcjQgrid and i got this exception.
System.NotSupportedException was unhandled by user code
Message=The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.
Though OrdeyBy is used before Skip method why it is generating the exception? How can it be solved?
I encountered the exception in the controller:
public ActionResult GridDataBasic(GridSettings gridSettings)
{
var jobdescription = sm.GetJobDescription(gridSettings);
var totalJobDescription = sm.CountJobDescription(gridSettings);
var jsonData = new
{
total = totalJobDescription / gridSettings.PageSize + 1,
page = gridSettings.PageIndex,
records = totalJobDescription,
rows = (
from j in jobdescription
select new
{
id = j.JobDescriptionID,
cell = new[]
{
j.JobDescriptionID.ToString(),
j.JobTitle,
j.JobType.JobTypeName,
j.JobPriority.JobPriorityName,
j.JobType.Rate.ToString(),
j.CreationDate.ToShortDateString(),
j.JobDeadline.ToShortDateString(),
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
GetJobDescription Method and CountJobDescription Method
public int CountJobDescription(GridSettings gridSettings)
{
var jobdescription = _dataContext.JobDescriptions.AsQueryable();
if (gridSettings.IsSearch)
{
jobdescription = gridSettings.Where.rules.Aggregate(jobdescription, FilterJobDescription);
}
return jobdescription.Count();
}
public IQueryable<JobDescription> GetJobDescription(GridSettings gridSettings)
{
var jobdescription = orderJobDescription(_dataContext.JobDescriptions.AsQueryable(), gridSettings.SortColumn, gridSettings.SortOrder);
if (gridSettings.IsSearch)
{
jobdescription = gridSettings.Where.rules.Aggregate(jobdescription, FilterJobDescription);
}
return jobdescription.Skip((gridSettings.PageIndex - 1) * gridSettings.PageSize).Take(gridSettings.PageSize);
}
And Finally FilterJobDescription and OrderJobDescription
private static IQueryable<JobDescription> FilterJobDescription(IQueryable<JobDescription> jobdescriptions, Rule rule)
{
if (rule.field == "JobDescriptionID")
{
int result;
if (!int.TryParse(rule.data, out result))
return jobdescriptions;
return jobdescriptions.Where(j => j.JobDescriptionID == Convert.ToInt32(rule.data));
}
// Similar Statements
return jobdescriptions;
}
private IQueryable<JobDescription> orderJobDescription(IQueryable<JobDescription> jobdescriptions, string sortColumn, string sortOrder)
{
if (sortColumn == "JobDescriptionID")
return (sortOrder == "desc") ? jobdescriptions.OrderByDescending(j => j.JobDescriptionID) : jobdescriptions.OrderBy(j => j.JobDescriptionID);
return jobdescriptions;
}
The exception means that you always need a sorted input if you apply Skip, also in the case that the user doesn't click on a column to sort by. I could imagine that no sort column is specified when you open the grid view for the first time before the user can even click on a column header. To catch this case I would suggest to define some default sorting that you want when no other sorting criterion is given, for example:
switch (sortColumn)
{
case "JobDescriptionID":
return (sortOrder == "desc")
? jobdescriptions.OrderByDescending(j => j.JobDescriptionID)
: jobdescriptions.OrderBy(j => j.JobDescriptionID);
case "JobDescriptionTitle":
return (sortOrder == "desc")
? jobdescriptions.OrderByDescending(j => j.JobDescriptionTitle)
: jobdescriptions.OrderBy(j => j.JobDescriptionTitle);
// etc.
default:
return jobdescriptions.OrderBy(j => j.JobDescriptionID);
}
Edit
About your follow-up problems according to your comment: You cannot use ToString() in a LINQ to Entities query. And the next problem would be that you cannot create a string array in a query. I would suggest to load the data from the DB with their native types and then convert afterwards to strings (and to the string array) in memory:
rows = (from j in jobdescription
select new
{
JobDescriptionID = j.JobDescriptionID,
JobTitle = j.JobTitle,
JobTypeName = j.JobType.JobTypeName,
JobPriorityName = j.JobPriority.JobPriorityName,
Rate = j.JobType.Rate,
CreationDate = j.CreationDate,
JobDeadline = j.JobDeadline
})
.AsEnumerable() // DB query runs here, the rest is in memory
.Select(a => new
{
id = a.JobDescriptionID,
cell = new[]
{
a.JobDescriptionID.ToString(),
a.JobTitle,
a.JobTypeName,
a.JobPriorityName,
a.Rate.ToString(),
a.CreationDate.ToShortDateString(),
a.JobDeadline.ToShortDateString()
}
})
.ToArray()
I had the same type of problem after sorting using some code from Adam Anderson that accepted a generic sort string in OrderBy.
After getting this excpetion, i did lots of research and found that very clever fix:
var query = SelectOrders(companyNo, sortExpression);
return Queryable.Skip(query, iStartRow).Take(iPageSize).ToList();
Hope that helps !
SP

how to improve the performance of function which takes almost 1 second in loading time (asp.net mvc 3)

I did a profile tracing to check what functions are taking long times , One of the method takes near 1 second and is called 10+ times and i guess it should be a candidate for review. I have included the method, Can anyone tell me how can it possible be improved.
[NonAction]
private ProductModel.ProductMiscModel PrepareProductMiscModel(Product product)
{
if (product == null)
throw new ArgumentNullException("product");
var model = new ProductModel.ProductMiscModel();
var productVariants = _productService.GetProductVariantsByProductId(product.Id);
var getManufactureImage = _manufacturerService.GetProductManufacturersByProductId(product.Id)
.Select(x =>
{
var m = x.Manufacturer.ToModel();
m.PictureModel.ImageUrl = _pictureService.GetPictureUrl(x.Manufacturer.PictureId, _mediaSetting.ManufacturerThumbPictureSize, true);
m.PictureModel.Title = string.Format(_localizationService.GetResource("Media.Manufacturer.ImageLinkTitleFormat"), m.Name);
m.PictureModel.AlternateText = string.Format(_localizationService.GetResource("Media.Manufacturer.ImageAlternateTextFormat"), m.Name);
return m;
})
.ToList();
model.manufactureName = getManufactureImage;
switch (productVariants.Count)
{
case 0:
{
//var productVariant = productVariants[0];
model.Sku = null;
model.ShowSku = false;
// model.attributeName = 0;
} break;
case 1:
//only one variant
{ var productVariant = productVariants[0];
model.Sku = productVariant.Sku; //null;
model.ShowSku = true;
// model.attributeName = _productAttributeService.GetProductVariantAttributesByProductVariantId(productVariant.Id);
model.productSpecification = _specificationAttributeService.GetProductSpecificationAttributesByProductId(productVariant.Product.Id);
}
break;
}
return model;
}
_manufactureService.GetProductManufactureByProductId
public virtual IList<ProductManufacturer> GetProductManufacturersByProductId(int productId, bool showHidden = false)
{
if (productId == 0)
return new List<ProductManufacturer>();
string key = string.Format(PRODUCTMANUFACTURERS_ALLBYPRODUCTID_KEY, showHidden, productId);
return _cacheManager.Get(key, () =>
{
var query = from pm in _productManufacturerRepository.Table
join m in _manufacturerRepository.Table on
pm.ManufacturerId equals m.Id
where pm.ProductId == productId &&
!m.Deleted &&
(showHidden || m.Published)
orderby pm.DisplayOrder
select pm;
var productManufacturers = query.ToList();
return productManufacturers;
});
}
Use StopWatch in the method to determine which part it is that takes long time.
you might want to include the picture url in the original list instead of traversing each item and call _pictureService.GetPictureUrl.

Can I have more than one profiled connection with MVC Mini Profiler?

I'd like to use a mixture of both Dapper and EF 4 in my MVC3 application. Is it possible to have more than one profiled connection, or share a profiled connection?
Yes, you can use the EF profiled connection with Dapper, here's what I ended up using.
private static DatabaseContext GetDatabaseContext()
{
using (MiniProfiler.Current.Step("Create Oracle EF Context"))
{
var pConn = ProfiledConnection;
return pConn.CreateObjectContext<DatabaseContext>();
}
}
private static EFProfiledDbConnection ProfiledConnection
{
get
{
using (MiniProfiler.Current.Step("Create Oracle Profiled Connection"))
{
var connectionString =
ConfigurationManager.ConnectionStrings["DatabaseContext"].ConnectionString;
var ecsb = new EntityConnectionStringBuilder(connectionString);
var oraConn = new OracleConnection(ecsb.ProviderConnectionString);
var pConn = new EFProfiledDbConnection(oraConn, MiniProfiler.Current);
return pConn;
}
}
}
Then I used them in this way
using (var ctx = GetDatabaseContext())
{
var result = ctx.SOME_EF_ENTITY.FirstOrDefault(c => c.LOGINNAME == username && c.PASSWORD == password);
return result;
}
and
const string sql = #"
SELECT ppro_status_code_id
FROM ppro_status_codes
WHERE table_name = 'CLIENT_FC_SHARED'
AND status_code = :status_code";
using (var cnn = ProfiledConnection)
{
cnn.Open();
var data = cnn.Query<dynamic>(sql, new { status_code = code });
var result = data.First();
var codeID = result.PPRO_STATUS_CODE_ID;
return codeID;
}

Resources