How to save changes in a DB for C# - c#

I am trying to save the changes here and I am getting an exception error on db.SaveChanges(); I am trying to enter some content to the database and its saying that it needs to be validated.
Here is the error:
Validation failed for one or more entities. See
'EntityValidationErrors' property for more details.
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details:
System.Data.Entity.Validation.DbEntityValidationException: Validation
failed for one or more entities. See 'EntityValidationErrors' property
for more details.
using (GameConnection db = new GameConnection())
{
Game newGame = new Game();
int GameID = 0;
if (Request.QueryString.Count > 0)
{
GameID = Convert.ToInt32(Request.QueryString["gameID"]);
newGame = (from game in db.Games
where game.gameID == GameID
select game).FirstOrDefault();
}
newGame.teamA = teamATextBox.Text;
newGame.teamB = teamBTextBox.Text;
if (GameID == 0)
{
db.Games.Add(newGame);
}
db.SaveChanges();
Response.Redirect("~/Default.aspx");
}
}

The error is stating that at least one of the validation rules failed before submitting the request to the database.
What you need to do is check your class definition for Game (or database table) and check for NotNull or other restrictions and check if your input matches all these constraints by debugging the Game object before db.SaveChanges();
Even better, add a catch to print to the Console the Properties that failed:
using (GameConnection db = new GameConnection())
{
Game newGame = new Game();
int GameID = 0;
if (Request.QueryString.Count > 0)
{
GameID = Convert.ToInt32(Request.QueryString["gameID"]);
newGame = (from game in db.Games
where game.gameID == GameID
select game).FirstOrDefault();
}
newGame.teamA = teamATextBox.Text;
newGame.teamB = teamBTextBox.Text;
if (GameID == 0)
{
db.Games.Add(newGame);
}
try
{
db.SaveChanges();
}
catch (DbEntityValidationException ex)
{
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine(ve.PropertyName + " " + ve.ErrorMessage);
}
}
Response.Redirect("~/Default.aspx");
}

Related

System.Data.Entity.Validation.DbEntityValidationException

I have a project that uses Entity Framework. While calling SaveChanges on my DbEntityValidationException, I get the following exception:
System.Data.Entity.Validation.DbEntityValidationException: 'Validation
failed for one or more entities. See 'EntityValidationErrors' property
for more details.'
This is all fine and dandy, but I don't want to attach a debugger every time this exception occurs. More over, in production environments I cannot easily attach a debugger so I have to go to great lengths to reproduce these errors.
How can I see the details hidden within the DbEntityValidationException?
private void btnCreateLetter_Click(object sender, EventArgs e)
{
using (TransactionScope TS = new TransactionScope())
{
try
{
Letter TblLetter = new Letter();
TblLetter.Subject = txtSubject.Text.Trim();
TblLetter.Abstract = txtAbstract.Text.Trim();
TblLetter.Body = ckeCKEditor.TextEditor.Text.Trim();
{
var LastLetterID = (from Letter in Database.Letters orderby Letter.LetterID descending select Letter).First();
TblLetter.LetterNO = PublicVariable.TodayDate.Substring(0, 4).Substring(2, 2) + PublicVariable.gDetermineJobLevel + "/" + (LastLetterID.LetterID + 1);
}
TblLetter.CreateDate = lblCreateDate.Text;
TblLetter.UserID = PublicVariable.gUserID;
if (rdbClassification.Checked == true)
{
TblLetter.SecurityType = 1;
}
else if (rdbConfidential.Checked == true)
{
TblLetter.SecurityType = 2;
}
else if (rdbSeries.Checked == true)
{
TblLetter.SecurityType = 3;
}
if (rdbActionType.Checked == true)
{
TblLetter.UrgencyType = 1;
}
else if (rdbInstantaneous.Checked == true)
{
TblLetter.UrgencyType = 2;
}
else if (rdbAnnie.Checked == true)
{
TblLetter.UrgencyType = 3;
}
TblLetter.ArchivesType = 1;
if (rdbFollowHas.Checked == true)
{
TblLetter.FollowType = 1;
}
else if (rdbFollowHasnoot.Checked == true)
{
TblLetter.FollowType = 2;
}
if (rdbAttachmentHas.Checked == true)
{
TblLetter.AttachmentType = 1;
}
else if (rdbAttachmentHasnot.Checked == true)
{
TblLetter.AttachmentType = 2;
}
TblLetter.ReadType = 1;
TblLetter.LetterType = 1;
TblLetter.DraftType = 1;
if (rdbResponseDeadlineHas.Checked == true)
{
TblLetter.AnswerType = 1;
TblLetter.AnswerReadLine = String.Format("{0:yyyy/MM/dd}", Convert.ToDateTime(pdpSetResponseDeadline.Value.Year.ToString() +
"/" + pdpSetResponseDeadline.Value.Month.ToString() + "/" + pdpSetResponseDeadline.Value.Day.ToString()));
}
else if (rdbResponseDeadlineHasnot.Checked == true)
{
TblLetter.AnswerType = 2;
}
Database.Letters.Add(TblLetter);
Database.SaveChanges();
if (rdbAttachmentHas.Checked == true)
{
if (lblPath.Text != "")
{
FileStream ObjectFileStream = new FileStream(lblPath.Text, FileMode.Open, FileAccess.Read);
int Lenght = Convert.ToInt32(ObjectFileStream.Length);
byte[] ObjectData;
ObjectData = new byte[Lenght];
string[] strPath = lblPath.Text.Split(Convert.ToChar(#"\"));
ObjectFileStream.Read(ObjectData, 0, Lenght);
ObjectFileStream.Close();
AttachFile TableAttachFile = new AttachFile();
TableAttachFile.FileSize = Lenght / 1024;
TableAttachFile.FileName = strPath[strPath.Length - 1];
TableAttachFile.FileData = ObjectData;
TableAttachFile.LetterID = TblLetter.LetterID;
Database.AttachFiles.Add(TableAttachFile);
Database.SaveChanges();
}
}
TS.Complete();
MessageBox.Show("saved", "ok", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (InvalidCastException ex)
{
MessageBox.Show(ex.ToString());
MessageBoxIcon.Error);
return;
}
}
}
You have to get the validation errors from the db.SaveChanges() method of the DatabaseContext object -- you can't get them where you are.
You can either modify the SaveChanges() method of your database context and wrap it in a try-catch block, or (since the class is partial) you can extend the partial class within your application and just override the SaveChanges() method.
There is a nice blog post about this called Easy way to improve DbEntityValidationException of Entity Framework here.
The essence of it is something like this:
public partial class NorthwindEntities
{
public override int SaveChanges()
{
try
{
return base.SaveChanges();
}
catch (DbEntityValidationException ex)
{
// Retrieve the error messages as a list of strings.
var errorMessages = ex.EntityValidationErrors
.SelectMany(x => x.ValidationErrors)
.Select(x => x.ErrorMessage);
// Join the list to a single string.
var fullErrorMessage = string.Join("; ", errorMessages);
// Combine the original exception message with the new one.
var exceptionMessage = string.Concat(ex.Message, " The validation errors are: ", fullErrorMessage);
// Throw a new DbEntityValidationException with the improved exception message.
throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors);
}
}
}
The blogger explains:
That’s it! The rest of your code will automatically use the overridden
SaveChanges so you don’t have to change anything else. From now on,
your exceptions will look like this:
System.Data.Entity.Validation.DbEntityValidationException: Validation
failed for one or more entities. See 'EntityValidationErrors' property
for more details. The validation errors are: The field PhoneNumber
must be a string or array type with a maximum length of '12'; The
LastName field is required.
The DbEntityValidationException also contains the entities that caused
the validation errors. So if you require even more information, you
can change the above code to output information about these entities.
As mention, you need to check on your EntityValidationError when it throws the exception.
You should fix that validation error, instead of asking bypass this exception.
Normally these errors are table allow length, data type, column does not allow null and etc. There will be exact fiend name mention in your exception too.

Can't save record using Entity Framework

My objects will not save no matter what I do they will fetch and get info and make a new record but not update.
This is the code that details with getting existing patient and then modifying the record setting the state then calling save change this is cracking my head the last three hours what is going wrong. I was told you had to change the entity state of an object before it would no if to save but when i try to attach it it says its already attached
Appointment _appointment = new Appointment();
int errorCount = 0;
Patient _patient = SourceDal.getPatientByPatientNewId(Convert.ToInt32(txtPatientId.Text));
_patient.SSN = txtSSN.Text;
_patient.FirstName = txtPatientFirstName.Text;
_patient.LastName = txtPatientLastName.Text;
_patient.Middle = txtPatientMiddle.Text;
_patient.AddressOne = txtPatientAddressOne.Text;
_patient.City = txtPatientCity.Text;
_patient.State = txtPatientState.Text;
_patient.ZipCode = txtPatientZip.Text;
_patient.HomePhone = txtPatientHomePhone.Text;
_patient.WorkPhone = txtPatientWorkPhone.Text;
_patient.CellPhone = txtPatientCellPhone.Text;
if (rBtnHomePhone.Checked == true)
// _patient.ApptPhone = txtPatientHomePhone.Text;
if (rBtnHomePhone.Checked == true)
// _patient.ApptPhone = txtPatientHomePhone.Text;
if (rBtnWorkPhone.Checked == true)
// _patient.ApptPhone = txtPatientWorkPhone.Text;
_patient.BirthDate = dtBirthDate.DateTime;
_patient.emailAddress = txtPatientEmail.Text;
_patient.Race = Convert.ToInt32(dpRace.SelectedValue);
_patient.Ethnicity =Convert.ToInt32(dpEthnicity.SelectedValue);
_patient.Language = Convert.ToInt32(dpLanguages.SelectedValue);
if (dpGender.Text == "")
{
dpGender.Focus();
errorCount = 1;
lblGenderRequired.Text = "* Gender is required.";
}
else
{
errorCount = 0;
lblGenderRequired.Visible = false;
}
_patient.Gender = "M";
_patient.PatientID = txtPatientId.Text;
SourceDal.SourceEntities.Patients.Attach(_patient);
SourceDal.SourceEntities.Patients.Context.ObjectStateManager.ChangeObjectState(_patient, EntityState.Modified);
SourceDal.SourceEntities.SaveChanges();
The error I get is
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Data.Entity.dll
Additional information: An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
Edit 2:
Code to show my function getPaitnetByPatineyNewId
public Patient getPatientByPatientNewId(int newId)
{
Patient patient = new Patient();
if (newId == -1)
{
patient = new Patient();
}
else
{
patient = SourceEntities.Patients
.Where(w => w.ID == newId)
.FirstOrDefault();
}
return patient;
}
I think you have some issues with proper separation of concerns within your DAL, but for the short solution, you should only add (and not attach) if it's a new entity
if (_patent.PatentId == 0)
{
_patient.PatientID = txtPatientId.Text; // If you're using an identity column, remove this line. I would also strongly suggest not letting the user change this...
SourceDal.SourceEntities.Patients.Add(_patient);
}
For Anyone else the above scenarios did not work for me so this is what I had to do. I put a flag on my forms isUpdate and check that on the save button then if save call similar to below then if add just call savechanges and its now working thank you for everyone help hope this help someone.
public void SaveProviders(Provider _providers)
{
try
{
using (var ctx = new SMBASchedulerEntities(this.Connectionstring))
{
ctx.Providers.Add(_providers);
ctx.Entry(_providers).State = System.Data.Entity.EntityState.Modified;
ctx.SaveChanges();
}
}
catch (DbEntityValidationException e)
{
foreach (var eve in e.EntityValidationErrors)
{
Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
eve.Entry.Entity.GetType().Name, eve.Entry.State);
foreach (var ve in eve.ValidationErrors)
{
Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
ve.PropertyName, ve.ErrorMessage);
}
}
throw;
}
}

'System.Data.Entity.Infrastructure.DbUpdateException' I dont know why my program is throwing me this error

I am an amateur to web programming.
Currently working with c#, MVC, js/ts, and jquery.
When I try and SaveChanges to my database I get this error:
" 'System.Data.Entity.Infrastructure.DbUpdateException' occurred in
EntityFramework.dll. Additional information: An error occurred while
updating the entries. See the inner exception for details. "
There are no inner details. This is what I am trying to do.
Order order = new Order();
TryUpdateModel(order);
try
{
if (string.Equals(values["PromoCode"], PromoCode,
StringComparison.OrdinalIgnoreCase) == false)
{
return View(order);
}
else
{
order.Username = User.Identity.Name;
order.OrderDate = DateTime.Now;
//Save Order
storeDB.Orders.Add(order);
storeDB.SaveChanges();
//Process the order
var cart = ShoppingCart.GetCart(this.HttpContext);
cart.CreateOrder(order);
return RedirectToAction("Complete",
new { id = order.OrderId });
}
}
catch (System.Data.Entity.Core.UpdateException e)
{
return View(order);
}
catch (System.Data.Entity.Infrastructure.DbUpdateException ex) //DbContext
{
Console.WriteLine(ex.InnerException);
return View(order);
}
catch (Exception ex)
{
Console.WriteLine(ex.InnerException);
//Invalid - redisplay with errors
return View(order);
}
it fails at cart.CreateOrder(order);
this is what CreateOrder(order) does
decimal orderTotal = 0;
var cartItems = GetCartItems();
// Iterate over the items in the cart,
// adding the order details for each
foreach (var item in cartItems)
{
var orderDetail = new OrderDetail
{
GameId = item.GameId,
OrderId = order.OrderId,
UnitPrice = item.Game.Price,
Quantity = item.Count
};
// Set the order total of the shopping cart
orderTotal += (item.Count * item.Game.Price);
storeDB.OrderDetails.Add(orderDetail);
}
// Set the order's total to the orderTotal count
order.Total = orderTotal;
// Save the order
storeDB.SaveChanges();
// Empty the shopping cart
EmptyCart();
// Return the OrderId as the confirmation number
return order.OrderId;
it gives me the error message at storeDB.SaveChanges();
everything is spelt the way it is suppose to.
Anything you guys think I am missing?
The DbUpdateException is caused by mostly database constraint violations. You should be showing the additional code to deal with the DbUpdateException:
try
{
....
}
catch (DbUpdateException ex)
{
UpdateException updateException = (UpdateException)ex.InnerException;
SqlException sqlException = (SqlException)updateException.InnerException;
foreach (SqlError error in sqlException.Errors)
{
// TODO: Do something with your errors
}
}
We figured it out. When saving our changes to the database we forgot to fill in a column for that entry. Very stupid =P. I was working with a partner and thought they took care of all that stuff.
Thanks guys

DbUpdateException was unhandled?

Hi so keep encountering this exception every time when savechanges() is called. There is an other post that has multiple answers but, I cannot pin point which answer is suitable for my problem. Also it seems that everyone has a different opinion about this exception.
Link to other post: [a link] Entity Framework: "Store update, insert, or delete statement affected an unexpected number of rows (0)."
My Exception:
An unhandled exception of type
'System.Data.Entity.Infrastructure.DbUpdateException' occurred in
EntityFramework.dll
Additional information: An error occurred while updating the entries.
See the inner exception for details.
I am trying to save mails into my storage. I am using entity framework 6.1.3 and SQL server 2014.
This is my method that stores mails:
public int StoreMail(PhishingMail PhishingMail)
{
using (var phishingMailStorage = new PhishFinderDBModel())
{
try
{
//// var manager = ((IObjectContextAdapter)phishingMailStorage).ObjectContext.ObjectStateManager;
//// phishingMailStorage.PhishingMail.Attach(PhishingMail);
phishingMailStorage.Entry(PhishingMail).State = PhishingMail.PhishingMailId == 0 ? EntityState.Added : EntityState.Modified;
phishingMailStorage.SaveChanges();
//// manager.ChangeObjectState(PhishingMail, EntityState.Modified);
//// phishingMailStorage.SaveChanges();
Console.WriteLine("Het is gelukt");
}
catch (OptimisticConcurrencyException)
{
var ctx = ((IObjectContextAdapter)phishingMailStorage).ObjectContext;
ctx.Refresh(RefreshMode.ClientWins, phishingMailStorage.PhishingMail);
phishingMailStorage.SaveChanges();
}
}
return PhishingMail.PhishingMailId;
}
This is my get mails method, that does work:
public List<PhishingMail> GetEmails()
{
phishingMailList = new List<PhishingMail>();
FolderId InboxId = new FolderId(WellKnownFolderName.Inbox, "******#******.nl");
FindItemsResults<Item> findResults = service.FindItems(InboxId, new ItemView(20));
foreach (Item phishingmail in findResults.Items)
{
if (!((EmailMessage)phishingmail).IsRead)
{
/// ((EmailMessage)phishingmail).IsRead = true;
((EmailMessage)phishingmail).Update(ConflictResolutionMode.AutoResolve);
}
PhishingMail mail = MailMapper.Map((EmailMessage)phishingmail);
//// ((EmailMessage)phishingmail).Load(new PropertySet(BasePropertySet.IdOnly, EmailMessageSchema.IsRead));
phishingMailList.Add(mail);
/// Console.WriteLine(mail.Type);
}
return phishingMailList;
}
Why does savechanges() not work and how do I make it work?
Thank you.
write your db.SaveChanges(); method inside a try block. It will tell you the exact problem
try
{
db.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException dbEx)
{
Exception raise = dbEx;
foreach (var validationErrors in dbEx.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
string message = string.Format("{0}:{1}",
validationErrors.Entry.Entity.ToString(),
validationError.ErrorMessage);
raise = new InvalidOperationException(message, raise);
}
}
throw raise;
}

An error occurred while preparing the command definition. See the inner exception for details EF

An error occurred while updating the entries. See the inner exception for details.
Inner exception : "An error occurred while preparing the command definition. See the inner exception for details."
I'm using Oracle as Entity Framework and Database.
When i am trying get result using EF it's working fine. But when i am trying to insert a record into the table I am getting this issue.
This is the code:
try{
Table1 Obj = new Table1();
Obj.col1 = 2010;
Obj.col2 =0;
Obj.col3 = 103907;
Obj.col4 = 14145;
DataContext1 dbContext = new DataContext1();
dbContext.AddToTable1(Obj);
dbContext.ObjectStateManager.ChangeObjectState(Obj,System.Data.EntityState.Added);
dbContext.SaveChanges();
}catch(Expectation ex)
{
}
You need to look at the inner exception. The issue will probably be obvious from there.
Something like this might help (or set a breakpoint and just look):
try{
Table1 Obj = new Table1();
Obj.col1 = 2010;
Obj.col2 =0;
Obj.col3 = 103907;
Obj.col4 = 14145;
DataContext1 dbContext = new DataContext1()
dbContext.AddToTable1(Obj);
dbContext.ObjectStateManager.ChangeObjectState(Obj,System.Data.EntityState.Added);
dbContext.SaveChanges();
}
catch (System.Data.Entity.Validation.DbEntityValidationException e)
{
string validationErrors = "DbEntityValidationException ValidationErrors: ";
foreach (var k in e.EntityValidationErrors)
{
foreach (var e1 in k.ValidationErrors)
{
validationErrors += string.Format("{0} - {1}; ", e1.PropertyName, e1.ErrorMessage);
}
}
throw new Exception(validationErrors, e);
}

Categories