optimization mvc code - asp.net-mvc

i have such code
var prj = _dataContext.Project.FirstOrDefault(p => p.isPopular == true);
if (prj != null)
{
prj.isPopular = false;
_dataContext.SaveChanges();
}
prj = Details(id);
prj.isPopular = true;
_dataContext.SaveChanges();
idea-i have only one record with value true in field isPopular, so i get it and make false, then i get object by id and make it isPopular true. i don't like 2 calls on savechanges.
any ideas?

var prj = _dataContext.Project.FirstOrDefault(p => p.isPopular == true || p.id ==id);
prj.Single(p => p.isPpopular == true).IsPopular = false;
prj.Single(p => p.isPpopular == id).IsPopular = true;
_dataContext.SaveChanges();

var prj = _dataContext.Project.FirstOrDefault(p => p.isPopular == true);
if (prj != null)
{
prj.isPopular = false;
}
var prj2 = Details(id);
prj2.isPopular = true;
_dataContext.SaveChanges();
Of course you should find better variable name for "prj2".

Related

Getting same Current and Original value of change tracker modified state

Below is my override saveChanges Methed which calls SetChanges Method
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
SetChanges();
OnBeforeSaving();
return base.SaveChanges(acceptAllChangesOnSuccess);
}
Right now, Sometimes code works completely fine but in some scenario It gives same value of both property.OriginalValue and property.CurrentValue for Modification so I am not able find what is the issue in my code
private void SetChanges()
{
Guid SystemLogId = Guid.NewGuid();
var currentDate = DateTime.Now;
var entitiesTracker = ChangeTracker.Entries()
.Where(p => p.State == EntityState.Modified || p.State == EntityState.Added).ToList();
foreach (var entry in entitiesTracker)
{
var pagename = entry.Entity.GetType().Name;
if (pagename != "ExceptionLog")
{
var rowid = 0;
try
{
rowid = int.Parse(entry.OriginalValues["Id"].ToString());
}
catch (Exception)
{ }
SystemLog sysLog = new SystemLog();
List<SystemChangeLog> changeLog = new List<SystemChangeLog>();
foreach (PropertyEntry property in entry.Properties)
{
string propertyName = property.Metadata.Name;
switch (entry.State)
{
case EntityState.Added:
sysLog.Event = "Created";
break;
case EntityState.Modified:
{
sysLog.Event = "Updated";
if (propertyName != "ModifiedDate" && propertyName != "CreatedDate" && propertyName != "ModifiedBy" && propertyName != "CreatedBy" && propertyName != "RowVersion")
{
var original = Convert.ToString(property.OriginalValue);
var current = Convert.ToString(property.CurrentValue);
if (property.IsModified && !original.Equals(current))
{
SystemChangeLog log = new SystemChangeLog()
{
Property = propertyName,
OldValue = original,
NewValue = current,
DateOfChange = currentDate,
rowid = rowid,
SystemLogId = SystemLogId.ToString(),
};
changeLog.Add(log);
}
}
}
break;
}
}
base.Set<SystemChangeLog>().AddRange(changeLog);
if(changeLog.Count() >0 || entry.State == EntityState.Added)
{
sysLog.UserId = UserId;
sysLog.Date = currentDate;
sysLog.Page = pagename;
sysLog.Location = ExceptionHandler(entry, "Location");
sysLog.IPAddress = ExceptionHandler(entry, "IPAddress");
sysLog.MACAddress = ExceptionHandler(entry, "MACAddress");
sysLog.SystemLogId = SystemLogId.ToString();
base.Set<SystemLog>().Add(sysLog);
}
}
}
}
And also Is there any way to make it fast for more than thousand entry
hope below code can help:
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
setChanges(); // to get new value and old value
var result = base.SaveChanges(acceptAllChangesOnSuccess);
OnAfterSaveChanges();// to get auto added id
return result;
}

how to save list of data in memory?

I have an ajax function which is called by the jquery-datatable and ve two responsibility.
To get data from the database.
To serve the search, sort, pagination like functional work.
Now all I need is I just wanna get data once and save it in memory so that when user type something in the search box it performs the search from stored data directly.
Here the code.
public ActionResult AjaxOil(JQueryDataTableParamModel param)
{
//To get data and should be run only once.
IEnumerable<Oil> allOils = _context.Oils.ToList();
//All others function.
IEnumerable<Oil> filteredOils;
if (!string.IsNullOrEmpty(param.sSearch))
{
filteredOils = allOils
.Where(c => c.CommonName.Contains(param.sSearch)
||
c.BotanicalName.Contains(param.sSearch)
||
c.PlantParts.Contains(param.sSearch)
||
c.Distillation.Contains(param.sSearch));
}
else
{
filteredOils = allOils;
}
var sortColumnIndex = Convert.ToInt32(Request["iSortCol_0"]);
Func<Oil, string> orderingFunction = (c => sortColumnIndex == 1 ? c.CommonName :
sortColumnIndex == 2 ? c.BotanicalName :
c.PlantParts);
var distillationFilter = Convert.ToString(Request["sSearch_4"]);
var commonFilter = Convert.ToString(Request["sSearch_1"]);
var botanicalFilter = Convert.ToString(Request["sSearch_2"]);
var plantFilter = Convert.ToString(Request["sSearch_3"]);
if (!string.IsNullOrEmpty(commonFilter))
{
filteredOils = filteredOils.Where(c => c.CommonName.Contains(commonFilter));
}
if (!string.IsNullOrEmpty(botanicalFilter))
{
filteredOils = filteredOils.Where(c => c.BotanicalName.Contains(botanicalFilter));
}
if (!string.IsNullOrEmpty(plantFilter))
{
filteredOils = filteredOils.Where(c => c.PlantParts.Contains(plantFilter));
}
if (!string.IsNullOrEmpty(distillationFilter))
{
filteredOils = filteredOils.Where(c => c.Distillation.Contains(distillationFilter));
}
var sortDirection = Request["sSortDir_0"];
if (sortDirection == "asc")
filteredOils = filteredOils.OrderBy(orderingFunction);
else
filteredOils = filteredOils.OrderByDescending(orderingFunction);
var displayedOils = filteredOils
.Skip(param.iDisplayStart)
.Take(param.iDisplayLength);
var result = from c in displayedOils
select new[] { Convert.ToString(c.OilId), c.CommonName, c.BotanicalName, c.PlantParts, c.Distillation };
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = allOils.Count(),
iTotalDisplayRecords = filteredOils.Count(),
aaData = result
},
JsonRequestBehavior.AllowGet);
On first load save the data in cache/session/static field. On next search check if the cache/session/static field is not null and read from there, not from db, else take again from db..
Example:
private static ObjectCache _cache = new MemoryCache("MemoryCache");
public List<Oils> GetDataFromCache(string keyName)
{
//private static ObjectCache _cache = new MemoryCache("keyName");
var data = _cache.Get(keyName);
if (data != null) return data as List<Oils>;
data = _context.Oils.ToList();
//keep the cache for 2h
_cache.Add(keyName, data, DateTimeOffset.Now.AddHours(2));
return data;
}
(didn't test the code, but that's the logic) or you can use Session if you prefer
Session example:
if(Session["Data_Oils"] != null) { return Session["Data_Oils"] as List<Oils; } else { var temp = _context.Oils.ToList(); Session["Data_Oils"] = temp; return temp; }

How to speed up ASP.NET MVC Excel file upload data validation against a stored procedure

I have an ASP.NET MVC application that uploads an Excel file with items that need to be validated against a stored procedure. This process works well if the Excel file has a few records, but now if I have more than over a hundred lines, it's very slow to validate.
Is there a way I can speed up his process somehow? Basically I write the data from the Excel file to a SQL Server database where I validate the data against a stored procedure. When I have about 50 records, it executes faster, as soon as I have over 100, it's very slow. Please see my code below and advise.
public ActionResult ValidateClaims()
{
var domainNameOfficial = Session["domainName"];
int sessionIdentifier = (int)Session["sessionID"];
var claimsRecords = db.CleanSupplierClaims.Where(x => x.CleanSupplierClaimsUploadSessionID == sessionIdentifier).ToList();
List<CleanSupplierClaim> supplierClaimsData = claimsRecords; //(List<CleanSupplierClaim>)TempData["supplierClaimsData"]; //= new List<CleanSupplierClaim>();// = claimsRecords;// My issue is here, I get all records and not the ones the user just uploaded
CleanSupplierClaimData supplierClaimUplaod = new CleanSupplierClaimData();
var sqlConnection = "data source=XXXXX;initial catalog=Embrace; User ID=XXXXX; Password=XXXXXXXX;";
using (SqlConnection conn = new SqlConnection(sqlConnection))
{
try
{
foreach (var claim in supplierClaimsData)
{
SqlCommand cmd = new SqlCommand();
cmd.CommandTimeout = 60;
cmd.CommandText = "CRM.Supplier_Claim_Upload";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#Invoice", SqlDbType.NVarChar).Value = claim.Line_Number;
cmd.Parameters.Add("#Amount", SqlDbType.Decimal).Value = claim.Total_Claim;
cmd.Connection = conn;
conn.Open();
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
claim.ST_Key = reader.GetString(reader.GetOrdinal("ST_Key"));
claim.Error_1 = reader.GetString(reader.GetOrdinal("Error1"));
string lineNumberDoesNotExist = "Error: Invoice line number does not exist";
if (claim.Error_1.StartsWith(lineNumberDoesNotExist))
{
continue;
}
claim.Warning = reader.GetString(reader.GetOrdinal("Warning"));
claim.Error_2 = reader.GetString(reader.GetOrdinal("Error2"));
string warningCleanInclusion = "Warning";
if (claim.ST_Key != null && string.IsNullOrEmpty(claim.Warning) && string.IsNullOrEmpty(claim.Error_1) && string.IsNullOrEmpty(claim.Error_2))
{
var existingClaimCount = db.GPClaimsReadyToImports.Count(a => a.ST_Key == claim.ST_Key && a.CleanSupplierClaimSessionID == claim.CleanSupplierClaimsUploadSessionID);
if (existingClaimCount == 0)
db.GPClaimsReadyToImports.Add(new GPClaimsReadyToImport
{
Id = claim.Id,
ST_Key = claim.ST_Key,
Warning = claim.Warning,
Action = claim.Action,
Claim_Reference = claim.ClaimReference,
Currency = claim.Currency,
Error_1 = claim.Error_1,
Error_2 = claim.Error_2,
Line_Number = claim.Line_Number,
Total_Claim = claim.Total_Claim,
Domain_Username = domainNameOfficial.ToString(),//claim.Domain_Username,
DateCreated = DateTime.Now,
ImportFlag = true,
ReadyForImport = true,
CleanSupplierClaimSessionID = sessionIdentifier
});
db.SaveChanges();
}
}
foreach (CleanSupplierClaim saveToDBClaim in supplierClaimsData)
{
db.CleanSupplierClaims.Attach(saveToDBClaim);
var entry = db.Entry(saveToDBClaim);
entry.Property(aa => aa.Line_Number).IsModified = true;
entry.Property(aa => aa.Total_Claim).IsModified = true;
entry.Property(aa => aa.Currency).IsModified = true;
entry.Property(aa => aa.ClaimReference).IsModified = true;
entry.Property(aa => aa.Action).IsModified = true;
entry.Property(aa => aa.Domain_Username).IsModified = true;
entry.Property(aa => aa.Error_1).IsModified = true;
entry.Property(aa => aa.Error_2).IsModified = true;
entry.Property(aa => aa.Warning).IsModified = true;
entry.Property(aa => aa.ImportFlag).IsModified = true;
entry.Property(aa => aa.ReadyForImport).IsModified = true;
db.Entry(saveToDBClaim).State = System.Data.Entity.EntityState.Modified;
db.SaveChanges();
}
conn.Close();
}
}
catch (Exception ex)
{
ViewBag.Error = ex.Message + ex.InnerException;
}
var warningCount = "Warning";
var errorOneCont = "Error";
var errorTwo = "ErrorTwo";
var countWarning = supplierClaimsData.Select(x => x.Warning).Count();
var countErrorOne = supplierClaimsData.Select(x => x.Error_1).Count();
var countErrorTwo = supplierClaimsData.Select(x => x.Error_2).Count();
var officialWarning = String.Concat("Warning", countWarning);
ViewBag.WarningCount = officialWarning;
ViewBag.ErrorOneCount = countErrorOne;
ViewBag.ErrorTwoCount = countErrorTwo;
Session["supplierClaimsData"] = supplierClaimsData;
return View("ValidateClaims", supplierClaimsData);
}
}
I would recomend to use EPPLUS Plugin, available of NuGet.
https://www.nuget.org/packages/EPPlus/
I had used it for my large excel and its working perfect and speedy and OLEDB is not required at Runtime.
You can find a quick tutorial here :
http://zeeshanumardotnet.blogspot.com/2011/06/creating-reports-in-excel-2007-using.html

how to validate that a name entered using mvc doesn't exist in database

i am using sql server which is case sensitive. How can i convert the data so that it may be validated without being case sensitive
CODE:-
using (var kk = new TeamRepository(context))
{
var data = new Team();
var find = kk.GetAll().ToString();
if (find.Any(x => x.TeamName == apview.TeamName))
{
return false;
}
else
{
var _pointrepo = new PointsRepositotry(context);
if (image != null)
{
apview.ImageMimeType = image.ContentType;
apview.TeamLogo = new byte[image.ContentLength];
image.InputStream.Read(apview.TeamLogo, 0, image.ContentLength);
}
data.TeamLogo = apview.TeamLogo;
data.TeamName = apview.TeamName;
data.TeamEmail = apview.TeamEmail;
data.Contact_Number = apview.ContactNumber;
data.TeamNickName = apview.TeamNickName;
data.YearEstablished = apview.YearEstablished;
var points = new Points();
points.TeamName = apview.TeamName;
data.ImageMimeType = apview.ImageMimeType;
return kk.Insert(data);
//_pointrepo.Insert(points);
}
you can use ToLower
find.Any(x => x.TeamName.ToLower() == apview.TeamName.ToLower())
https://msdn.microsoft.com/en-us/library/e78f86at%28v=vs.110%29.aspx

Search with predicate builder in mvc4

Below is my method of searching using predicate builder there is no error showing in visual studio but the problem is that the below code is not executing.
public JsonResult GetSearchedGraph(string searchItem, string itemTypeEnum)
{
var pre = PredicateBuilder.True<Graph>();
pre.And(m => m.isHidden == false && m.ItemType!="FOLDER");
if (!String.IsNullOrEmpty(searchItem))
{
pre.And(m => m.GraphItemTitle.ToUpper().Contains(searchItem.ToUpper()));
}
if (!String.IsNullOrEmpty(itemTypeEnum))
{
pre.And(m => m.ItemType == itemTypeEnum);
}
var searchGraph = from m in db.Graphs.AsQueryable() select m;
searchGraph = db.Graphs.Where(pre);
return Json(searchGraph.ToList(), JsonRequestBehavior.AllowGet);
}
I am not getting any search result by using this method what it is wrong with this code?
well, you just have to do correct assignments.
because pre.And() doesn't impact pre
var pre = PredicateBuilder.True<Graph>();
//assign result of pre.And(xxx) to pre
pre = pre.And(m => m.isHidden == false && m.ItemType!="FOLDER");
if (!String.IsNullOrEmpty(searchItem))
{
//same
pre = pre.And(m => m.GraphItemTitle.ToUpper().Contains(searchItem.ToUpper()));
}
if (!String.IsNullOrEmpty(itemTypeEnum))
{
//same
pre = pre.And(m => m.ItemType == itemTypeEnum);
}

Resources