I have a table with orders(around 8000 records),
The table takes a few seconds to load.
The reason for that is because one of the field shown on the page is being retrieved from another table
(returnProductName).
when removing this function the table loads fast.
When loading the records I'm using Skip and Take but when retrieving the product name i'm iterating all the Orders since if the user wants to search by product name it will show all results with this product.
The product table is not big (around 70 records)
I can't figure out why the function will make the page load so slow.
I know i can just add the product name column to the table and populate it when ever adding new orders,
but this doesn't sounds right,
Can anyone tell me the reason for this delay?
returnProductName Function :
public string returnProductName(int productId)
{
return (_unitOfWork.Product.GetAll().Where(q => q.Id == productId).Select(q =>
q.ProductName)).FirstOrDefault();
}
Function that loads the page data:
[HttpPost]
public ActionResult GetList()
{
//Server Side parameters
int start = Convert.ToInt32(Request.Form["start"].FirstOrDefault());
int length = Convert.ToInt32(Request.Form["length"].FirstOrDefault());
string searchValue = Request.Form["search[value]"].FirstOrDefault();
string sortColumnName = Request.Form["columns["+Request.Form["order[0][column]"]+"][name]"].FirstOrDefault();
string sortDirection = Request.Form["order[0][dir]"].FirstOrDefault();
List<Order> orderList = new List<Order>();
orderList = _unitOfWork.Order.GetAll().ToList();//Working Fast
int totalRows = orderList.Count;
foreach (Order order in orderList)
{
order.ProductName = returnProductName(order.ProductId);
}
if (!string.IsNullOrEmpty(searchValue))
{
orderList = orderList.Where(x => x.FullAddress.ToLower().Contains(searchValue.ToLower())
x.Id.ToString().Contains(searchValue.ToLower()) ||
x.OrderStatus.ToLower().Contains(searchValue.ToLower()) ||
x.ProductName.ToLower().Contains(searchValue.ToLower()) |||
x.Quantity.ToString().Contains(searchValue.ToLower()) ||
x.Cost.ToString().Contains(searchValue.ToLower()) ||
(!string.IsNullOrEmpty(x.TrackingNumber) && x.TrackingNumber.ToString().Contains(searchValue.ToLower()))
).ToList<Order>();
}
int totalRowsAfterFiltering = orderList.Count;
orderList = orderList.Skip(start).Take(length).ToList<Order>();
return Json(new { data = orderList, draw = Request.Form["draw"], recordsTotal = totalRows ,
recordsFiltered = totalRowsAfterFiltering});
}
I would perhaps consider updating the GetAll() method or creating another one which returns a dictionary.
In this case GetAllById() and then updating returnProductName which I would rename to GetProductName():
// Or whatever your type is
public Dictionary<int, List<Product>> GetAllById()
{
// your code..
return data
.GroupBy(x => x.Id)
.ToDictionary(x => x.Key, x => x.ToList());
}
public string GetProductName(int productId)
{
var products = _unitOfWork.Product.GetAllById();
return products[productId].FirstOrDefault(q => q.ProductName);
}
how I can update a single value for an already existing row in the db by only having a parameters that I want to add it to this attribute
here is my code for a trivial way but didnt work
public bool BuyBook(int BookId, int UserId, int BookPrice){
using (var ctx = new OnlineBooksEntities())
{
User updatedCustomer = (from c in ctx.Users
where c.UserId == UserId
select c).FirstOrDefault();
updatedCustomer.Balance = BookPrice;
ctx.SaveChanges();
}
this.DeleteBook(BookId);
return true;
}
Add an sql query to the method solves the update aim
public bool BuyBook(int BookId, int UserId, int BookPrice)
{
try
{
using (var ctx = new OnlineBooksEntities())
{
User user = ctx.Users.Where(x => x.UserId == UserId).FirstOrDefault();
BookPrice = (int)user.Balance + BookPrice;
int noOfRowUpdated =
ctx.Database.ExecuteSqlCommand("Update Users set Balance = "+BookPrice+ " where UserId ="+UserId);
}
Updating basically means changing an existing row's value. Since you mentioned EF, you can do this by retrieving the object, changing its value, and saving it back. Thus you can do something like this:
using (var db = new MyContextDB())
{
var result = db.Books.SingleOrDefault(b => b.BookPrice == bookPrice);
if (result != null)
{
result.SomeValue = "Your new value here";
db.SaveChanges();
}
}
How to save mixed data in multiple tables if is checked checkbox:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "rID,AgentID,karta_br,Datum,patnikID,stanicaOD,stanicaDO,cena,povratna")] tbl_rezervacii tbl_rezervacii)
{
if (ModelState.IsValid)
{
if (tbl_rezervacii.povratna != true)
{
db.tbl_rezervacii.Add(tbl_rezervacii);
db.SaveChanges();
}
else
{
tbl_rezervacii rezervacii = new tbl_rezervacii()
{
???????????????????????
};
db.tbl_rezervacii.Add(rezervacii);
db.SaveChanges();
tbl_povratni povratni = new tbl_povratni()
{
???????????????????????
};
db.tbl_povratni.Add(povratni);
db.SaveChanges();
}
This is code in the controller, and I need to mix data from two forms, and save to two tables, I need something like this, and now my problem is just in else section of implementation.
I make application for Bus Ticket system, and i need this if is checked return way checkbox to add: rID (related with first table tbl_rezervacii), date of returning and relation of returning, include same agent id, price, etc. data which is saved in first tbl_rezervacii table.
MODIFIED CONTROLLER CODE:
public ActionResult Create([Bind(Include = "rID,AgentID,karta_br,Datum,patnikID,stanicaOD,stanicaDO,cena,povratna")] tbl_rezervacii tbl_rezervacii )
{
if (ModelState.IsValid)
{
if (tbl_rezervacii.povratna != true)
{
db.tbl_rezervacii.Add(tbl_rezervacii);
db.SaveChanges();
}
else
{
tbl_rezervacii rezervacii = new tbl_rezervacii()
{
AgentID = tbl_rezervacii.AgentID,
karta_br = tbl_rezervacii.karta_br,
Datum = tbl_rezervacii.Datum,
patnikID = tbl_rezervacii.patnikID,
stanicaOD = tbl_rezervacii.stanicaOD,
stanicaDO = tbl_rezervacii.stanicaDO,
cena = tbl_rezervacii.cena,
povratna = tbl_rezervacii.povratna
};
db.tbl_rezervacii.Add(rezervacii);
//db.SaveChanges();
var rows = db.SaveChanges();
tbl_povratni povratna = new tbl_povratni()
{
rezID = rezervacii.rID,
AgentID = rezervacii.AgentID,
karta_br = rezervacii.karta_br,
DatumP = **tbl_povratni.DatumP**,
patnikID = rezervacii.patnikID,
stanicaPOD = **tbl_povratni.stanicaPOD**,
stanicaPDO = **tbl_povratni.stanicaPDO**,
};
db.tbl_povratni.Add(povratna);
db.SaveChanges();
}
ViewBag.AgentID = new SelectList(db.tbl_agenti, "aID", "agent_ime", tbl_rezervacii.AgentID);
ViewBag.patnikID = new SelectList(db.tbl_patnici, "pID", "ime", tbl_rezervacii.patnikID);
ViewBag.stanicaOD = new SelectList(db.tbl_stanici, "sID", "stanica", tbl_rezervacii.stanicaOD);
ViewBag.stanicaDO = new SelectList(db.tbl_stanici, "sID", "stanica", tbl_rezervacii.stanicaDO);
ViewBag.stanicaPOD = new SelectList(db.tbl_stanici, "sID", "stanica", tbl_rezervacii.tbl_povratni.stanicaPOD);
ViewBag.stanicaPDO = new SelectList(db.tbl_stanici, "sID", "stanica", tbl_rezervacii.tbl_povratni.stanicaPDO);
return View(tbl_rezervacii);
}
return RedirectToAction("Index");
}
How to take data from secondary form and save together in second table?
So, if checkbox is checked, you want to save data into two tables and use primary key of first table (rID) in second table? If rID is auto increment, It will be updated by EF with the value assigned by the database.
tbl_rezervacii rezervacii = new tbl_rezervacii()
{
AgentID = tbl_rezervacii.AgendID,
karta_br = tbl_rezervacii.karta_br
// and so on...
};
db.tbl_rezervacii.Add(rezervacii);
var rows = db.SaveChanges(); // optional, rows will be > 0 if saved successfully.
tbl_povratni povratni = new tbl_povratni()
{
// if rID is auto increment
rID = rezervacii.rID,
// and so on...
};
db.tbl_povratni.Add(povratni);
db.SaveChanges();
I've a model that includes some data, but when the modelstate isn't valid it needs to fill up the model again. So i have to fill multiple times my model. So i would like to make a function that returns the model for me, so i can use it in my controller. How can i achieve this?
Thanks for reading.
I simply tried to make a public string.
This is my code:
public string LaadGastenboek(int id)
{
Models.Berichten Gastenboek = new Models.Berichten();
Models.Gastenboekmaken Gastenboekberichtmaken = new Models.Gastenboekmaken();
int hoeveelzoudenermoetenzijn = id * 10 - 9;
if (SQL.ReturnSingleINTResult("Select count(*) from Gastenboek where status = 1") >= hoeveelzoudenermoetenzijn)
{
String Gastenboekunsorted = SQL.LaadGastenboek(hoeveelzoudenermoetenzijn);
// Gastenboek data -- Properties
int tellerhtml = 1;
int teller = 1;
// Array
if (Gastenboekunsorted != null)
{
string[] ArrayGastenboek = Gastenboekunsorted.Split('*');
// Split alles, 1 bericht is 3 data
for (int nummer = 0; ArrayGastenboek.Count() > nummer - 1; nummer++)
{
if (tellerhtml == 3)
{
Models.GastenBoekBerichtenModel item = new Models.GastenBoekBerichtenModel();
// Bereken het verschil, - 4 omdat hij begint te tellen bij 0
tellerhtml = teller - 4;
// Zet t/m 3 van arraygastenboek in de html code
// Bericht - Naam - Datum
item.Bericht = ArrayGastenboek[tellerhtml + 1];
item.Naam = ArrayGastenboek[tellerhtml + 2];
item.Datum = ArrayGastenboek[tellerhtml + 3];
Gastenboek.Add(item);
// Reset
tellerhtml = 0;
}
teller++;
tellerhtml++;
}
}
}
return (new Models.GastenboekOverall(Gastenboek, Gastenboekberichtmaken));
}
From your comment:
"The question is how i can modify my code that it returns a model."
I assume you want to modify your code to return model.
public Models.GastenboekOverall LaadGastenboek(int id)
{
... your code here ...
return (new Models.GastenboekOverall(Gastenboek, Gastenboekberichtmaken));
}
In your controller to pass the model into view you can write, assuming your view consume model Models.GastenboekOverall.
public ActionResult Index()
{
return view (LaadGastenboek(someId));
}
I'm have a settings view where I'm using MT.D to build out my UI. I just got it to read elements from a database to populate the elements in a section.
What I don't know how to do is access each elements properties or values. I want to style the element with a different background color for each item based on it's value in the database. I also want to be able to get the selected value so that I can update it in the db. Here's the rendering of the code that does the UI stuff with MT.D. I can get the values to show up and slide out like their supposed to... but, styling or adding delegates to them to handle clicks I'm lost.
List<StyledStringElement> clientTypes = SettingsController.GetClientTypes ();
public SettingsiPhoneView () : base (new RootElement("Home"), true)
{
Root = new RootElement("Settings") {
new Section ("Types") {
new RootElement ("Types") {
new Section ("Client Types") {
from ct in clientTypes
select (Element) ct
}
},
new StringElement ("Other Types")
}
Here's how I handled it below. Basically you have to create the element in a foreach loop and then populate the delegate with whatever you want to do there. Like so:
public static List<StyledStringElement> GetClientTypesAsElement ()
{
List<ClientType> clientTypes = new List<ClientType> ();
List<StyledStringElement> ctStringElements = new List<StyledStringElement> ();
using (var db = new SQLite.SQLiteConnection(Database.db)) {
var query = db.Table<ClientType> ().Where (ct => ct.IsActive == true && ct.Description != "Default");
foreach (ClientType ct in query)
clientTypes.Add (ct);
}
foreach (ClientType ct in clientTypes) {
// Build RGB values from the hex stored in the db (Hex example : #0E40BF)
UIColor bgColor = UIColor.Clear.FromHexString(ct.Color, 1.0f);
var localRef = ct;
StyledStringElement element = new StyledStringElement(ct.Type, delegate {
ClientTypeView.EditClientTypeView(localRef.Type, localRef.ClientTypeId);
});
element.BackgroundColor = bgColor;
ctStringElements.Add (element);
}
return ctStringElements;
}