I'm new to both ADO .NET and MVC, and I am trying to do something simple where I am editting a "DailyReport", which is basically representing a work-report.
Here's my relevant controller pattern:
//
// GET: /DailyReport/Edit/5
public ActionResult Edit(int id, int weeklyReportID, int day)
{
WeeklyReport weeklyReport = (
from WeeklyReport wr in db.WeeklyReports
where wr.Id == weeklyReportID select wr)
.FirstOrDefault();
ViewBag.Week = weeklyReport.Week;
ViewBag.Day = day;
return View();
}
//
// POST: /DailyReport/Edit/5
[HttpPost]
public ActionResult Edit(DailyReport dailyReport, int weeklyReportID, int day)
{
if (ModelState.IsValid)
{
db.SaveChanges();
if (dailyReport == null)
{
dailyReport = new DailyReport();
dailyReport.StartTime = new TimeSpan(7, 0, 0);
dailyReport.EndTime = new TimeSpan(7 + 8, 0, 0);
dailyReport.Day = day;
db.DailyReports.AddObject(dailyReport);
db.SaveChanges();
}
WeeklyReport weeklyReport = (
from WeeklyReport wr in db.WeeklyReports
where wr.Id == weeklyReportID select wr)
.FirstOrDefault();
if (!weeklyReport.DailyReport.Any(dr => dr.Id == dailyReport.Id))
{
weeklyReport.DailyReport.Add(dailyReport);
}
dailyReport.WeeklyReport = weeklyReport;
db.SaveChanges();
return RedirectToAction("Edit",
"WeeklyReport",
new {
id = weeklyReportID,
week = weeklyReport.Week,
year = weeklyReport.Year
});
}
return View(dailyReport);
}
When I am editting the datetime value, it doesn't get saved. In the HttpPost section when I debug it, the object is indeed changed to reflect these changes, but calling db.SaveChanges() doesn't commit it to the database.
Edit "db" in this case is my ADO .NET context, declared in the following way:
ActivesEntities db = new ActivesEntities();
ActivesEntities has this declaration:
public partial class ActivesEntities : ObjectContext { ... }
First of all, I would recommend you to not call the db.SaveChanges until you really need to save an Entity object in the middle of the series of Transactional Steps..
Because Entity Framework support saving all the EntityContext object in a single shot !
And I think you may try changing the code like this,
[HttpPost]
public ActionResult Edit(DailyReport dailyReport, int weeklyReportID, int day)
{
if (ModelState.IsValid)
{
if (dailyReport == null)
{
dailyReport = new DailyReport();
dailyReport.StartTime = new TimeSpan(7, 0, 0);
dailyReport.EndTime = new TimeSpan(7 + 8, 0, 0);
dailyReport.Day = day;
db.DailyReports.AddObject(dailyReport);
}
WeeklyReport weeklyReport = (from WeeklyReport wr in db.WeeklyReports where wr.Id == weeklyReportID select wr).SingleOrDefault();
if (!weeklyReport.DailyReport.Any(dr => dr.Id == dailyReport.Id))
{
weeklyReport.DailyReport.Add(dailyReport);
}
dailyReport.WeeklyReport = weeklyReport;
db.SaveChanges();
return RedirectToAction("Edit", "WeeklyReport", new { id = weeklyReportID, week = weeklyReport.Week, year = weeklyReport.Year });
}
I think using if you are Updating the entity object then you need to call SingleOrDefault and not FirstOrDefault. I do it like this on Linq2Sql..
you are using entity framework right? it's a bit different from ADO.NET (it uses it but those are not 100% same thing), we should add the tag EF to the question.
said so, why do you call db.SaveChanges twice? I would not call it at the top of your Edit method.
also, as I see in some EF examples, you can use Add and not AddObject.
check this one:
How to: Add, Modify, and Delete Objects
last thing, your StartTime and EndTime properties of the object are of type TimeSpan and not datetime?
Related
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();
// Inside an action result
tp = dbContext.tp.Single(x => ...);
foreach (Sample sample in tp.samples)
{
if (sample.SampleStatusId == 1)
changeSamplestatus(sample, 2, now); //change samples to on hold
}
dbContext.SaveChanges();
public void changeSamplestatus(Sample sample, int sampleStatus, DateTime now)
{
sample.SampleHistory.Add(new SampleHistory
{
OldStatus = sample.SampleStatusId,
NewStatus = sampleStatus,
});
sample.SampleStatusId = sampleStatus;
}
I have an entity (sample) that I would like to change it status.
I am calling a function to do so, but the entity doesn't get modified (but it is creating a new row in history table with the correct FK).
It doesn't throw any errors when SaveChanges is called. It just doesn't modify the entity.
You can try:
//INSIDE AN ACTION RESULT
var tp = dbContext.tp.SingleOrDefault(x => ...);
if (tp != null)
{
foreach (Sample sample in tp.samples)
{
if (sample.SampleStatusId == 1)
changeSamplestatus(sample, 2, DateTime.Now);
}
int flag = dbContext.SaveChanges();
if (flag > 0)
{
// update successful
}
}
public void changeSamplestatus(Sample sample, int sampleStatus, DateTime now)
{
//sample.SampleHistory.Add(new SampleHistory
//{
// OldStatus = sample.SampleStatusId,
// NewStatus = sampleStatus,
//});
sample.SampleStatusId = sampleStatus;
}
Don't use Single for this case, because it would throw exception if no result was found or there were more than 1 result. Use SingleOrDefault or FirstOrDefault instead.
You can try this . I hope thiw will work . The Idea is to get the history records first in the context and then update the propterties and set state to mofifed . Please try I didnt tested it but it should work.
public void changeSamplestatus(Sample sample, int sampleStatus, DateTime now)
{
var historyRecordToUpdate = db.SampleHistory.FirstOrDefault(h=>h.id == sampleHistoryId )
if(historyRecordToUpdate !=null )
{
db.Entry(sample).State= EntityState.Modified;
sample.SampleStatusId = sampleStatus;
}
}
I Create A News Site With MVC5 But I Have Problem .
in Model i Create A Repository Folder And in this i Create Rep_Setting for
Connect to Tbl_Setting in DataBase .
public class Rep_Setting
{
DataBase db = new DataBase();
public Tbl_Setting Tools()
{
try
{
var qGetSetting = (from a in db.Tbl_Setting
select a).FirstOrDefault();
return qGetSetting;
}
catch (Exception)
{
return null;
}
}
}
And i Create a Rep_News for Main Page .
DataBase db = new DataBase();
Rep_Setting RSetting = new Rep_Setting();
public List<Tbl_News> GetNews()
{
try
{
List<Tbl_News> qGetNews = (from a in db.Tbl_News
where a.Type.Equals("News")
select a).OrderByDescending(s => s.ID).Skip(0).Take(RSetting.Tools().CountNewsInPage).ToList();
return qGetNews;
}
catch (Exception ex)
{
return null;
}
}
But This Code Have Error to Me
OrderByDescending(s=>s.ID).Skip(0).Take(RSetting.Tools().CountNewsInPage).ToList();
Error :
Error 18 'System.Linq.IQueryable<NewsSite.Models.Domain.Tbl_News>' does
not contain a definition for 'Take' and the best extension method overload
'System.Linq.Queryable.Take<TSource>(System.Linq.IQueryable<TSource>, int)' has
some invalid arguments
E:\MyProject\NewsSite\NewsSite\Models\Repository\Rep_News.cs 50 52 NewsSite
How i Resolve it ?
Try it this way. The plan of debugging is to split your execution, this also makes for a more reusable method in many cases. And a good idea is to avoid using null and nullables if you can, if you use them "on purpose" the you must have a plan for them.
DataBase db = new DataBase();
Rep_Setting RSetting = new Rep_Setting();
public List<Tbl_News> GetNews()
{
int skip = 0;
Tbl_Setting tools = RSetting.Tools();
if(tools == null){ throw new Exception("Found no rows in the database table Tbl_Setting"); }
int? take = tools.CountNewsInPage;//Nullable
if(!take.HasValue)
{
// Do you want to do something if its null maybe set it to 0 and not null
take = 0;
}
string typeStr = "News";
List<Tbl_News> qGetNews = (from a in db.Tbl_News
where a.Type.Equals(typeStr)
select a).OrderByDescending(s => s.ID).Skip(skip).Take(take.Value);
return qGetNews.ToList();
}
if qGetNews is a empty list you now don't break everything after trying to iterate on it, like your return null would. instead if returning null for a lit return a new List<>() instead, gives you a more resilient result.
So I said reusable method, its more like a single action. So you work it around to this. Now you have something really reusable.
public List<Tbl_News> GetNews(string typeStr, int take, int skip = 0)
{
List<Tbl_News> qGetNews = (from a in db.Tbl_News
where a.Type.Equals(typeStr)
select a).OrderByDescending(s => s.ID).Skip(skip).Take(take);
return qGetNews.ToList();
}
Infact you shjould always try to avoid returning null if you can.
public class Rep_Setting
{
DataBase db = new DataBase();
public Tbl_Setting Tools()
{
var qGetSetting = (from a in db.Tbl_Setting
select a).FirstOrDefault();
if(qGetSetting == null){ throw new Exception("Found no rows in the database table Tbl_Setting"); }
return qGetSetting;
}
}
Hi I am developing an application in MVC3. and i am stuck at one place. Everytime when control goes to IIndex1 action its argument value has become 0. But it should be same as value in IIndex action argument. I have used session, ViewBag, ViewData but my problem is remains. Please suggest me.
public ActionResult GetMDN(string msisdn)
{
number = msisdn.Substring(0, msisdn.IndexOf('$'));
if (number.ToLower() != "unknown" && number.Length == 12)
{
number = number.Remove(0, 2);
}
Session["msdresponse"] = number;
Session["moptr"] = msisdn.Substring(msisdn.LastIndexOf('$') + 1);
number = msisdn;
int sngid=int.Parse(ViewData["isongid"].ToString());
return RedirectToAction("IIndex1", new { iid = sngid });
}
public ActionResult IIndex(int id)
{
ViewBag.isongid = id;
ViewData["isongid"] = id;
Response.Redirect("http:XXXXXXXXXXXXXXXX");
return RedirectToAction("GetMDN");
}
public ActionResult IIndex1(int iid)
{
}
You can use TempData.You can pass every types of data between to action, whether they are in same controller or not. Your code should be something like it:
public ActionResult GetMDN(string msisdn)
{
int sngid=10;
TempData["ID"] = sngid;
return RedirectToAction("IIndex");
}
public ActionResult IIndex()
{
int id = Convert.ToInt32(TempData["ID"]);// id will be 10;
}
Use TempData instead of ViewData/ViewBag to store data that should persist after redirect.
ViewData/ViewBag allow to pass value from controller to view.
Something to read on this subject:
http://www.codeproject.com/Articles/476967/WhatplusisplusViewData-cplusViewBagplusandplusTem
http://msdn.microsoft.com/en-us/library/dd394711(v=vs.100).aspx
you can use TempData["name"] = variableToPass;