My code to use the function for updating is here and it works also
[HttpPost]
public bool SaveDefCompny(DefCompanyDTO DefCmpny)
{
using (RPDBEntities db = new RPDBEntities())
{
using (TransactionScope trans = new TransactionScope())
{
//the problem is here incase of saving
var UpdateDefCmpnyId = (from CmpnyId in db.DefCompanies
where CmpnyId.Id == DefCmpny.Id
select CmpnyId).First();
List<DefCompany> list = new List<DefCompany>();
list.Add(UpdateDefCmpnyId);
try
{
foreach (DefCompany DefCmpny1 in list)
{
DefCmpny1.Id = DefCmpny1.Id;
DefCmpny1.ShortName = DefCmpny.ShortName;
DefCmpny1.FullName = DefCmpny.FullName;
DefCmpny1.ContactPerson = DefCmpny.ContactPerson;
DefCmpny1.Address1 = DefCmpny.Address1;
DefCmpny1.CompanyCity = DefCmpny.CompanyCity;
DefCmpny1.CompanyState = DefCmpny.CompanyState;
DefCmpny1.CompanyCountry = DefCmpny.CompanyCountry;
DefCmpny1.ZipPostCode = DefCmpny.ZipPostCode;
DefCmpny1.TelArea = DefCmpny.TelArea;
DefCmpny1.CurrentCurrencyCode = DefCmpny.CurrentCurrencyCode;
db.SaveChanges();
trans.Complete();
}
}
catch (Exception ex)
{
}
}
return false;
}
}
when I try to save instead of updating the line of code
var UpdateDefCmpnyId = (from CmpnyId in db.DefCompanies
where CmpnyId.Id == DefCmpny.Id
select CmpnyId).First();
gives null value and hence saving fails because record is new and not present in database so how to handle null in case of saving how to use try catch so that when value is null it proceed to saving code that add
How about something along these lines:
var UpdateDefCmpnyId = (from CmpnyId in db.DefCompanies
where CmpnyId.Id == DefCmpny.Id
select CmpnyId).FirstOrDefault();
if(UpdateDefCmpnyId == null)
{
//insert
//(handle the id however you need to for insert. depending on your setup, you might be able to leave it empty and let the database put it in for you)
}
else
{
//update
//set the id as you do in the question
}
Related
I'm using Database First in my website and i'm trying to update the data of one entry of the database but the changes are not being saved in one part but are working in another one.
This is where i populate the form with the model data or create a new one to reserve the ID:
public ActionResult Editar(int ID = 0)
{
var banner = new Banner();
var siteVM = new SiteViewModel();
if (ID == 0)
{
db.Banner.Add(banner);
db.SaveChanges();
}
else
{
banner = db.Banner.Find(ID);
siteVM.iePaginas = db.Pagina.ToList().Select(x => new SelectListItem
{
Value = x.ID.ToString(CultureInfo.InvariantCulture),
Text = x.nome.ToUpper()
}).ToList();
foreach (var pagina in siteVM.iePaginas)
{
foreach (var bannerPagina in banner.BannerPagina)
{
if (int.Parse(pagina.Value) == bannerPagina.paginaID)
{
pagina.Selected = true;
}
}
}
}
siteVM.Banner = banner;
return View(siteVM);
}
And this is where i save it:
[HttpPost]
public ViewResult Editar(SiteViewModel model)
{
try
{
var banner = model.Banner;
banner.rascunho = !banner.ativo;
if (banner.ID == 0)
{
db.Banner.Add(banner);
}
else
{
db.Entry(banner).State = EntityState.Modified;
}
//Remove the related pages
foreach (var source in db.BannerPagina.Where(x => x.bannerID == banner.ID))
{
db.BannerPagina.Remove(source);
}
//Record related pages
foreach (var pag in model.PaginasSelecionadas)
{
db.BannerPagina.Add(new BannerPagina { paginaID = int.Parse(pag.Value), bannerID = banner.ID });
}
db.SaveChanges();
ViewBag.Salvo = 1;
return View(model);
}
catch
{
ViewBag.Error = 1;
return View(model);
}
}
The db.Entry(banner).State = EntityState.Modified; doesn't work, i get the data in the model and my ModeState is valid but the data isn't changed on the database. Just below that i have:
db.BannerPagina.Remove(source); //BannerPagina contains a set of pages that are related to my banner so i can choose the pages i want this banner displayed
db.BannerPagina.Add(new BannerPagina { paginaID = int.Parse(pag.Value), bannerID = banner.ID });
And they work fine. I also have tried to use the attach method but it also doesn't work.
EDIT
Kind of found my problem, earlier i had changed the StoreGeneratedPattern option on my table properties to Computed instead of None (I did that so i could create an empty object in the database using it's default values), once i changed it back my changes started to be saved in the DB.
Is there a way to make the Computed configuration work ?
I'm having trouble figuring out how to determine if a number is duplicated.
Right now, the process is when the user clicks on a button to browse for an xml file, the xml file gets deserialized and stored into db and the data gets shown on a DataGrid on the view.
So, I added a confirmation dialog so when the user clicks on browse, the code checks to see if the lot_number being deserialized is a duplicate or not from inside a column from a table in database. I only want the user to be able to add lot numbers to db that are not duplicates.
Here's my code so far:
public void DeSerializationStream(string filePath)
{
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "lot_information";
xRoot.IsNullable = false;
// Create an instance of lotinformation class.
var lot = new LotInformation();
// Create an instance of stream writer.
TextReader txtReader = new StreamReader(filePath);
// Create and instance of XmlSerializer class.
XmlSerializer xmlSerializer = new XmlSerializer(typeof(LotInformation), xRoot);
// DeSerialize from the StreamReader
lot = (LotInformation)xmlSerializer.Deserialize(txtReader);
// Close the stream reader
txtReader.Close();
}
public void ReadLot(LotInformation lot)
{
try
{
using (var db = new DDataContext())
{
var lotNumDb = db.LotInformation.FirstOrDefault(r => r.lot_number.Equals(r.lot_number));
if (lotNumDb != null || lotNumDb.lot_number.ToString().Equals(lot.lot_number))
{
confirmationWindow.Message = LanguageResources.Resource.Sample_Exists_Already;
dialogService.ShowDialog(LanguageResources.Resource.Error, confirmationWindow);
}
else {
Console.WriteLine("lot does not exist. yay");
}
DateTime ExpirationDate = lot.exp_date;
if (ExpirationDate != null)
{
if (DateTime.Compare(ExpirationDate, DateTime.Now) > 0)
{
try
{
LotInformation lotInfo = db.LotInformation.FirstOrDefault(r => r.lot_number.Equals(lotNumber));
}
catch (InvalidOperationException e)
{
//TODO: Add a Dialog Here
}
}
else
{
Console.WriteLine(ExpirationDate);
errorWindow.Message = LanguageResources.Resource.Lot_Expired;
dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
}
}
else
{
errorWindow.Message = LanguageResources.Resource.Lot_Not_In_Database;
dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
}
}
}
catch
{
errorWindow.Message = LanguageResources.Resource.Database_Error;
dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
logger.writeErrLog(LanguageResources.Resource.Database_Error);
}
}
I think I'm just having problems with when to grab the lot_number in this process.
This part below gives me problems. It keeps showing the Sample Exists already message for unique lot numbers that I'm uploading and I'm not sure why. I think it's a problem with my LINQ query but I'm not sure how to fix it. Any ideas?
var lotNumDb = db.LotInformation.FirstOrDefault(r => r.lot_number.Equals(r.lot_number));
if (lotNumDb != null || lotNumDb.lot_number.ToString().Equals(lot.lot_number))
{
confirmationWindow.Message = LanguageResources.Resource.Sample_Exists_Already;
dialogService.ShowDialog(LanguageResources.Resource.Error, confirmationWindow);
}
else {
Console.WriteLine("lot does not exist. yay");
}
you can't use like this:
db.LotInformation.FirstOrDefault(r => r.lot_number.Equals(r.lot_number))
may be :
db.LotInformation.FirstOrDefault(r => r.lot_number.Equals(lot.lot_number))
or
db.LotInformation.FirstOrDefault(r => r.lot_number.Equals(a string))
Details
I have 2 tables (Procedures, Surgeons) with a lookup table (ProcSurg) to create a many to many relationship.
scar_Requests scar_Procedures scar_ProcSurg scar_Surgeons
------------- --------------- ------------- -------------
RequestID <> ProcedureID <> ProcedureID(fk) <> SurgeonID
... RequestID SurgeonID(fk) ...
...
A single request can have multiple procedures and each procedure can have multiple surgeons.
Everything saves correctly until I have 2 procedures each that share the same Surgeon.
Error: InvalidOperationException was unhandled
The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.
I separated out the code for saving this part of the record to try to isolate my problem..
Addprocedures is a class that contains 1 Procedure and a list of Surgeons
class Procedure
{
public scar_Procedures Procedure { get; set; }
public List<scar_Surgeons> Surgeons { get; set; }
public void RemoveSurgeon(int SurgeonID)
{
Surgeons.Remove(Surgeons.Where(x => x.SurgeonID == SurgeonID).FirstOrDefault());
}
public Procedure()
{
Surgeons = new List<scar_Surgeons>();
}
}
Saving code: using DBContext
private void SaveProcSurg()
{
using (MCASURGContext db2 = new MCASURGContext())
{
foreach (Procedure p in AddProcedures)
{
if (p.Procedure.RequestID == 0)
{
p.Procedure.RequestID = ReqID;
}
p.Procedure.scar_Surgeons.Clear();
foreach (scar_Surgeons s in p.Surgeons)
{
if (db2.ChangeTracker.Entries<scar_Surgeons>().Where(x => x.Entity.SurgeonID == s.SurgeonID).FirstOrDefault() == null)
{
db2.scar_Surgeons.Attach(s);
}
p.Procedure.scar_Surgeons.Add(s);
}
if (p.Procedure.ProcedureID == 0)
{
db2.scar_Procedures.Add(p.Procedure);
db2.Entry(p.Procedure).State = System.Data.Entity.EntityState.Added;
}
else
{
db2.scar_Procedures.Attach(p.Procedure);
db2.Entry(p.Procedure).State = System.Data.Entity.EntityState.Modified;
}
}
db2.SaveChanges();
}
}
I've tried several different ways of saving the record and this is the closest I've come to doing it correctly.
I feel like it has something to do with the way I'm attaching the surgeons to the entity and then to the procedure. Any help, idea's or suggestions on where I can find an answer would be great!
I've been searching google endlessly for over a week and I've been trying to wrap my mind around what exactly Entity Framework is doing but I'm still pretty new to this.
Edited 9/24/2013
Sorry this is the complete code snippet from the comments section with the req variable included
//Internal variable
private scar_Requests req;
private List<Procedure> AddProcedures = new List<Procedure>();
//Gets a scar_Request from the DB
private void GetRequest()
{
using (MCASURGContext db = new MCASURGContext())
{
req = db.scar_Requests.Include("scar_Procedures.scar_Surgeons").Include("scar_Status").Include("scar_Users.scar_Service").Where(x => x.RequestID == ReqID).FirstOrDefault();
foreach (scar_Procedures p in req.scar_Procedures) { AddProcedures.Add(new Procedure() { Proc = p, Surgeons = p.scar_Surgeons.ToList() }); }
}
}
Keeping with good form I'll post my answer since I think I figured it out. Maybe it will help someone in the future.
I completely re-wrote the saving and cut out a lot of useless code that I was using before and less calls to the DB. There was other methods that I didn't post above that saved other parts of the record that I condensed into a single method.
Basically I get the record and its joined tables from the DB and iterate through all the fields/joined tables that need to be updated and save it back to the DB. (Seems super obvious now but I tried this way before and I must have had something wrong because it didn't work the first few times I tried it this way.)
I don't know if its 100% correct or written up to normal coding standards and I still have some final tweaking to do before its completely done.
private void SaveProcSurg()
{
using (MCASURGContext db2 = new MCASURGContext())
{
//Get Record from DB
scar_Requests sReq = db2.scar_Requests.Include("scar_Users").Include("scar_Status").Include("scar_Procedures.scar_Surgeons").Where(x => x.RequestID == ReqID).FirstOrDefault();
//Update Record fields
sReq.CreationDate = req.CreationDate == null ? DateTime.Now : req.CreationDate = req.CreationDate;
sReq.DateOfSurgery = dtpDateOfSurgery.Value;
sReq.IsDeleted = false;
sReq.IsScheduled = false;
sReq.LatexAllergy = cbLatexAllergy.Checked;
sReq.ModifiedDate = DateTime.Now;
sReq.MRN = txtMRN.Text;
sReq.PatientName = txtPatientName.Text;
foreach (RadioButton rb in gbPatientType.Controls) if (rb.Checked == true) sReq.PatientType = rb.Text;
sReq.PreOpDiagnosis = txtPreOpDiag.Text;
sReq.PrimarySurgeon = txtPrimarySurgeon.Text;
sReq.PrivateComment = txtPrivateComment.Text;
sReq.PublicComment = txtPublicComment.Text;
sReq.RequestID = ReqID;
sReq.StatusID = req.StatusID;
sReq.UserID = req.UserID;
//Update Users/Status
sReq.scar_Users = db2.scar_Users.Where(x => x.UserID == sReq.UserID).FirstOrDefault();
sReq.scar_Status = db2.scar_Status.Where(x => x.StatusID == req.StatusID).FirstOrDefault();
//Attach to DBContext
db2.scar_Requests.Attach(sReq);
//Update Procedures
foreach (Procedure p in AddProcedures)
{
scar_Procedures pro = sReq.scar_Procedures.Where(x => x.ProcedureID == p.Proc.ProcedureID && p.Proc.ProcedureID != 0).FirstOrDefault();
if (pro != null)
{
pro.EnRecovery = p.Proc.EnRecovery;
pro.IsPrimary = p.Proc.IsPrimary;
pro.Laterality = p.Proc.Laterality;
pro.OrthoFastTrack = p.Proc.OrthoFastTrack;
pro.ProcedureID = p.Proc.ProcedureID;
pro.ProcedureText = p.Proc.ProcedureText;
pro.RequestID = ReqID;
pro.Site = p.Proc.Site;
}
else
{
pro = new scar_Procedures();
pro.EnRecovery = p.Proc.EnRecovery;
pro.IsPrimary = p.Proc.IsPrimary;
pro.Laterality = p.Proc.Laterality;
pro.OrthoFastTrack = p.Proc.OrthoFastTrack;
pro.ProcedureID = p.Proc.ProcedureID;
pro.ProcedureText = p.Proc.ProcedureText;
pro.RequestID = ReqID;
pro.Site = p.Proc.Site; ;
pro.scar_Requests = sReq;
}
//Update Surgeons
pro.scar_Surgeons.Clear();
foreach (scar_Surgeons s in p.Surgeons)
{
pro.scar_Surgeons.Add(db2.scar_Surgeons.Where(x=> x.SurgeonID == s.SurgeonID).FirstOrDefault());
}
}
//Set State and Save
db2.Entry(sReq).State = System.Data.Entity.EntityState.Modified;
db2.SaveChanges();
}
}
I am using session.query,first time its return latest database records and we populate on grid after editing on fields we save on database and then we again execute this query then it is not getting the updated record from database. the fields has updated in database but not getting updated record.
My NHibernate query is given below
List<FiscalPeriod> lstPeriods = new List<FiscalPeriod>();
using (var tr = session.BeginTransaction())
{
try
{
List<TSCFiscalPeriod> lstFiscalPeriods = session.Query<TSCFiscalPeriod>().ToList();
if (lstFiscalPeriods != null && lstFiscalPeriods.Count > 0)
{
foreach (var period in lstFiscalPeriods)
{
FiscalPeriod objPeriod = new FiscalPeriod();
objPeriod.Period = period.Id.FPeriod;
objPeriod.Name = "Period " + objPeriod.Period;
objPeriod.CompanyID = period.Id.FCompanyID;
objPeriod.Year = period.Id.FFiscalYear;
objPeriod.Begin = period.FBeginDate;
objPeriod.End = period.FEndDate;
objPeriod.OpenAP = FOpenAP(period.FOpen);
objPeriod.OpenGL = FOpenGL(period.FOpen);
objPeriod.SCFiscalPeriod = period;
objPeriod.IsExisting = true;
lstPeriods.Add(objPeriod);
}
}
tr.Commit();
}
catch (Exception ex)
{
lstPeriods = null;
CusException cex = new CusException(ex);
cex.Write();
}
return lstPeriods;
}
Is there any refresh method or something i am doing wrong.
Any help will be appreciated.thanks
make sure you are using session.clear() or session.flush() after save the session.
Nhibernate session is a static initializer.
Sometimes session is not able to refresh values.
So You have to flush and clear the session
session.flush();
session.clear();
I am LINQ to input information from a Database. I have my try.catch block set up to catch these exceptions. However I believe I ran into a sore spot where I am attempting to see what the message is but it just bypass printing the message to me and goes directly to error page. Here is an example of the code I have so far. I would love to get some input on why this seems to be acting so strange.
private void CreateEntry()
{
var date = DateTime.Today;
var version = (from v in house.StayLateVersions
where v.Active
select v).FirstOrDefault();
if (version == null)
{
throw new NullReferenceException();
}
//Try to create an entry for the database. Upon failure, sends the exception to ThrowDbError();
try
{
ResidenceHallInspection rhi = new ResidenceHallInspection();
rhi.versionId = version.id;
rhi.submitDate = DateTime.Now;
rhi.CheckInOrOut = ddlCheck.SelectedItem.Text;
rhi.Id = txtId.Text;
rhi.FirstName = txtFirstName.Text;
rhi.MiddleName = txtMiddleName.Text;
rhi.LastName = txtLastName.Text;
rhi.Walls = chbxWalls.SelectedItem.Text;
rhi.Windows = chbxWindows.SelectedItem.Text;
rhi.Blinds = chbxBlinds.SelectedItem.Text;
rhi.Couch = chbxCouch.SelectedItem.Text;
rhi.CommonRoomCouch = chbxCRCouch.SelectedItem.Text;
rhi.CommonRoomChair = chbxCRChair.SelectedItem.Text;
rhi.Doors = chbxDoors.SelectedItem.Text;
rhi.Carpet = chbxCarpet.SelectedItem.Text;
rhi.Ceiling = chbxCeiling.SelectedItem.Text;
rhi.CommonRoomCounter = chbxCRCounter.SelectedItem.Text;
rhi.Cabinet = chbxCabinet.SelectedItem.Text;
rhi.Phone = chbxPhone.SelectedItem.Text;
rhi.Bed = chbxBed.SelectedItem.Text;
rhi.Desk = chbxDesk.SelectedItem.Text;
rhi.DeskChairs = chbxDeskChair.SelectedItem.Text;
rhi.Tub = chbxTub.SelectedItem.Text;
rhi.Vanity = chbxVanity.SelectedItem.Text;
rhi.Notes = txtNotes.Text;
rhi.Building = txtResHall.Text;
rhi.ApartmentNumber = txtSuitNo.Text;
rhi.BedSpace = txtBedSpace.Text;
house.AddToResidenceHallInspections(rhi);
house.SaveChanges();
}
catch (Exception oe)
{
ThrowDbError(oe);
Response.Write(oe.InnerException);
}
}
/*=================================================*/
/*Possible Errors */
/*=================================================*/
private void ThrowDbError(Exception oe)
{
Response.Write(oe.Source);
house.Dispose();
Session.Contents.Add("FormException", oe);
Response.Redirect("/Database-Error/", true);
}
The most likely reason for that to happen is that you are running the database version query outside the try/catch block. Any exception in this db access code will not be handled by the code you have shown above.
Try extending your try block to also include the db access code:
var version = (from v in house.StayLateVersions
where v.Active
select v).FirstOrDefault();
if (version == null)
{
throw new NullReferenceException();
}
and see if this time the error is caught.