SaveChanges() not taking any affect - c#

I'm using Entity Framework to add new records to the database, everything goes right without any exceptions, but I don't see the new record the database, here is the code:
aSham_MeterReading meterReading = new aSham_MeterReading();
meterReading.TimeStampUTC = reading.TimeOfReading;
meterReading.TimeStampLocal = reading.TimeOfReading.ToLocalTime();
meterReading.Value = reading.Reading * this.Translate(this.MeterUnitsEnum, reading.FactorIndex);
meterReading.Meter = meter;
meterReading.CreateDate = DateTime.Now;
meterReading.UpdateDate = DateTime.Now;
meterReading.RowStatus = "Active";
db.aSham_MeterReading.Add(meterReading);
db.SaveChanges();
The code above is called like 20 times per second, is there any chance that this is related to the problem?
Any help would be appreciated.

You can check for the return value from db.SaveChanges() , if it is actually successful , it returns 1 . This will let you know if the operation was actually successful or not
int returnCode = db.SaveChanges();
if(returnCode == 1 )
{
Console.WriteLine("Success");
}
else
{
Console.WriteLine("Something gone wrong");
}

Related

SubmitChanges not updating, but inserts new record. LINQ to SQL

I am having difficulties UPDATING the databes via LINQ to SQL, inserting a new record works fine.
The code correctly inserts a new row and adds a primary key, the issue I am having is when I go to update (chnage a value that is already in the database) that same row the database is not updating, it is the else part of the code that does not work correctly. This is strange b/c the DB is properly connected and functioning through the fact that the DataContext inserts a new row with no issues. Checking the database confirms this.
This is the code,
using System;
using System.Collections.Generic;
using System.Linq;
using Cost = Invoices.Tenant_Cost_TBL;
namespace Invoices
{
class CollectionGridEvents
{
static string conn = Settings.Default.Invoice_DbConnectionString;
public static void CostDataGridCellEditing(DataGridRowEditEndingEventArgs e)
{
using (DatabaseDataContext DataContext = new DatabaseDataContext(conn))
{
var sDselectedRow = e.Row.Item as Cost;
if (sDselectedRow == null) return;
if (sDselectedRow.ID == 0)
{
sDselectedRow.ID = DateTime.UtcNow.Ticks;
DataContext.Tenant_Cost_TBLs.InsertOnSubmit(sDselectedRow);
}
else
{
// these two lines are just for debuging
long lineToUpdateID = 636154619329526649; // this is the line to be updated primary key
long id = sDselectedRow.ID; // this is to check the primary key on selected line is same
// these 3 lines are to ensure I am entering actual data into the DB
int? amount = sDselectedRow.Cost_Amount;
string name = sDselectedRow.Cost_Name;
int? quantity = sDselectedRow.Cost_Quantity;
sDselectedRow.Cost_Amount = amount;
sDselectedRow.Cost_Name = name;
sDselectedRow.Cost_Quantity = quantity;
}
try
{
DataContext.SubmitChanges();
}
catch (Exception ex)
{
Alert.Error("Did not save", "Error", ex);
}
}
}
}
}
And I am calling the method from this,
private void CostDataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
{
CollectionGridEvents.CostDataGridCellEditing(e);
}
The lineToUpdateID is copied dirrectly from the database and is just there to check against the currently selected rows primary key is the same, so I know I am trying to update the same row.
I have looked through as many of the same type of issues here on SO , such as this one Linq-to-Sql SubmitChanges not updating fields … why?. But still no closer to finding out what is going wrong.
Any ideas would be much appreciated.
EDIT: Cost is just short hand of this using Cost = Invoices.Tenant_Cost_TBL;
You cannot do that. You need to get the record out of the database and then update that record. Then save it back. Like this:
else
{
// first get it
var query =
from ord in DataContext.Tenant_Cost_TBLs
where ord.lineToUpdateID = 636154619329526649
select ord;
// then update it
// Most likely you will have one record here
foreach (Tenant_Cost_TBLs ord in query)
{
ord.Cost_Amount = sDselectedRow.Cost_Amount;
// ... and the rest
// Insert any additional changes to column values.
}
}
try
{
DataContext.SubmitChanges();
}
catch (Exception ex)
{
Alert.Error("Did not save", "Error", ex);
}
Here is an example you can follow.
Or you can use a direct query if you do not want to select first.
DataContext.ExecuteCommand("update Tenant_Cost_TBLs set Cost_Amount =0 where ...", null);
Your object (Cost) is not attached to DB context. You should attach it then save changes. Check solution here

Dynamics CRM SDK: Execute Multiple Requests for Bulk Update of around 5000 Records

I have written a function to update Default Price List for all the Active Products on the CRM 2013 Online.
//The method takes IOrganization service and total number of records to be created as input
private void UpdateMultipleProducts(IOrganizationService service, int batchSize, EntityCollection UpdateProductsCollection, Guid PriceListGuid)
{
//To execute the request we have to add the Microsoft.Xrm.Sdk of the latest SDK as reference
ExecuteMultipleRequest req = new ExecuteMultipleRequest();
req.Requests = new OrganizationRequestCollection();
req.Settings = new ExecuteMultipleSettings();
req.Settings.ContinueOnError = true;
req.Settings.ReturnResponses = true;
try
{
foreach (var entity in UpdateProductsCollection.Entities)
{
UpdateRequest updateRequest = new UpdateRequest { Target = entity };
entity.Attributes["pricelevelid"] = new EntityReference("pricelevel", PriceListGuid);
req.Requests.Add(updateRequest);
}
var res = service.Execute(req) as ExecuteMultipleResponse; //Execute the collection of requests
}
//If the BatchSize exceeds 1000 fault will be thrown.In the catch block divide the records into batchable records and create
catch (FaultException<OrganizationServiceFault> fault)
{
if (fault.Detail.ErrorDetails.Contains("MaxBatchSize"))
{
var allowedBatchSize = Convert.ToInt32(fault.Detail.ErrorDetails["MaxBatchSize"]);
int remainingCreates = batchSize;
while (remainingCreates > 0)
{
var recordsToCreate = Math.Min(remainingCreates, allowedBatchSize);
UpdateMultipleProducts(service, recordsToCreate, UpdateProductsCollection, PriceListGuid);
remainingCreates -= recordsToCreate;
}
}
}
}
Code Description : There are around 5000 active product records in the System. So I am updating Default Price List for all of them using above code.
But, I am missing here something so that, it has updated only 438 records. It loops through the While statement correctly, but it is not updating all of them here.
What should be the Batchsize when we run this function for the First Time?
Any one can help me here?
Thank you,
Mittal.
You pass remainingCreates as the batchSize parameter but your code never references batchSize so you are just going to reenter that while loop every time.
Also, I'm not sure how you are doing all your error handling but you need to update your catch block so that it doesn't just let FaultExceptions pass-through if they don't contain a MaxBatchSize value. Right now, if you take a FaultException regarding something other than batch size it will be ignored.
{
if (fault.Detail.ErrorDetails.Contains("MaxBatchSize"))
{
var allowedBatchSize = Convert.ToInt32(fault.Detail.ErrorDetails["MaxBatchSize"]);
int remainingCreates = batchSize;
while (remainingCreates > 0)
{
var recordsToCreate = Math.Min(remainingCreates, allowedBatchSize);
UpdateMultipleProducts(service, recordsToCreate, UpdateProductsCollection, PriceListGuid);
remainingCreates -= recordsToCreate;
}
}
else throw;
}
Instead of reactive handling, i prefer proactive handling of the MaxBatchSize, this is true when you already know what is MaxMatchSize is.
Following is sample code, here while adding OrgRequest to collection i keep count of batch and when it exceeds I call Execute and reset the collection to take fresh batch.
foreach (DataRow dr in statusTable.Rows)
{
Entity updEntity = new Entity("ABZ_NBA");
updEntity["ABZ_NBAid"] = query.ToList().Where(a => a.NotificationNumber == dr["QNMUM"].ToString()).FirstOrDefault().TroubleTicketId;
//updEntity["ABZ_makerfccall"] = false;
updEntity["ABZ_rfccall"] = null;
updEntity[cNBAttribute.Key] = dr["test"];
req.Requests.Add(new UpdateRequest() { Target = updEntity });
if (req.Requests.Count == 1000)
{
responseWithResults = (ExecuteMultipleResponse)_orgSvc.Execute(req);
req.Requests = new OrganizationRequestCollection();
}
}
if (req.Requests.Count > 0)
{
responseWithResults = (ExecuteMultipleResponse)_orgSvc.Execute(req);
}

Update works only for last method call

I have a quite simple UPDATE statement and it works correctly but for only one call. I have few projects (FAIs) in database and I want to change responsible person.
If I want to change two or more responsibles it only changes the responsible person for the last project. I don't have any error messages. All values are correctly send to update query but the query just does not send it to the database.
public void updateFaiUBazu(string orderNumber, FAI fai, int serialNumber)
{
konekcija.Open();
MessageBox.Show(fai.Reviewer);
komanda = new SqlCommand("
update FAI set
AircraftFK = #AircraftFK, GlassFK = #GlassFK, PartNumber = #PartNumber,
SerialNumber = #SerialNumber, ReportNumber = #ReportNumber,
Reviewer = #Reviewer, Comment = #Comment, DateTime = #DateTime,
Iges = #Iges, IgesName = #IgesName, Status = #Status
where
AircraftFK = " + fai.AircraftFK1 +
" and GlassFK = " + fai.GlassFK1 +
" and SerialNumber = " + serialNumber,
konekcija);
try
{
komanda.Parameters.Clear();
komanda.Parameters.AddWithValue("#AircraftFK", fai.AircraftFK1);
komanda.Parameters.AddWithValue("#GlassFK", fai.GlassFK1);
// komanda.Parameters.AddWithValue("#OrderNumberFK", fai[i].OrderNumerFK);
komanda.Parameters.AddWithValue("#PartNumber", fai.PartNumber);
komanda.Parameters.AddWithValue("#SerialNumber", fai.SerialNumber);
komanda.Parameters.AddWithValue("#ReportNumber", fai.ReportNumber);
komanda.Parameters.AddWithValue("#Reviewer", fai.Reviewer);
komanda.Parameters.AddWithValue("#Comment", fai.Comment);
komanda.Parameters.Add("#DateTime", fai.DateAndTime);
if (fai.IgesFile.Length != 0)
{
komanda.Parameters.AddWithValue("#Iges", fai.IgesFile);
}
else
{
komanda.Parameters.Add("#Iges", SqlDbType.VarBinary, -1);
komanda.Parameters["#Iges"].Value = DBNull.Value;
}
if (string.IsNullOrEmpty(fai.IgesName))
{
komanda.Parameters.Add("#IgesName", fai.IgesName).Value = DBNull.Value;
}
else
{
komanda.Parameters.AddWithValue("#IgesName", fai.IgesName);
}
komanda.Parameters.AddWithValue("#Status", "Not Tested");
komanda.ExecuteNonQuery();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
konekcija.Close();
}
Could that be some limitation with SqlServer update statement?
Follow a couple of steps to get to your problem.
Log yout update queries. JUst after you have created it. This will tell you if your updates are really executed when you are calling them from a loop.
If all your updates are logged, copy them to SSMS query window and execute them one by one in sequence. This would give you corect idea if there is anything wong with way queries are getting formed, or of there is any specific value in one of the parameters which is causing the problem. This will also help you identify if the problem specified by #Steve above exists.

Sys.WebForms.PageRequestManagerServerErrorException: An entity object cannot be referenced by multiple instances of IEntityChangeTracker

Story:
I have a strange error when I try to save something I got this error message
An entity object cannot be referenced by multiple instances of IEntityChangeTracker.
I really don’t know what that is and why is it appear, it appears only when I try to save something my insert and update is working, only when I try to save something in db from my Telerik grid
if (this.annualVacationList != null)
{
List<AnnualVacation> vacationToSave = this.annualVacationList;
IEnumerable<AnnualVacation> existing = paramUser.AnnualVacations;
foreach (AnnualVacation toSave in vacationToSave)
{
AnnualVacation existingItem = existing.Where(x => x.AnnualVacationId == toSave.AnnualVacationId).SingleOrDefault();
if (existingItem == null)
{
ctx.AddToAnnualVacations(toSave);
}
else
{
existingItem.FromDate = toSave.FromDate;
existingItem.ToDate = toSave.ToDate;
existingItem.WorkingTime = toSave.WorkingTime;
existingItem.VacationDays = toSave.VacationDays;
}
}
}
ctx.SaveChanges();
}
After debugging I have seen that the code brake down in the Project.Name.Designer.cs
..... O.o
public void AddToAnnualVacations(AnnualVacation annualVacation)
{
base.AddObject("AnnualVacations", annualVacation);
}
Heey
I got it by myself somehow viewstates are not Detaching the context and that was the problem I have just created
var tmp = new AnnualVacation
{
FromDate = toSave.FromDate,
ToDate = toSave.ToDate,
WorkingTime = toSave.WorkingTime,
VacationDays = toSave.VacationDays,
UserId = toSave.UserId
};
in the same if query that is above (if(existing Item==null)) and it works
but still thanks for everyone that tried to help me ^^

Insert with Linq-to-SQL sometimes fails

I have a project that inserts personal information to a table and details into another table. But sometimes personal information cannot be recorded, however details are recorded. As below code part, firstly personal information are inserted, then details. But sometimes personal information doesn't get saved and userId returns 0, So details are saved. I don't know why it doesn't work. Any idea?
public int ConferenceIdyeGoreKisiBilgileriniKaydet(string orderId)
{
KisiselBilgilerBal kisiBilgileri = (KisiselBilgilerBal)Session["kisiselBilgilerSession"];
registrationCode = GenerateGeristrationCode();
string toplamMaliyet = Session["toplamOdeme"].ToString();
PersonalInformation.SavePersonalInformations(kisiBilgileri, registrationCode,conferenceName);
int userId = AuthorPaperDetaylari.AdVeSoyadaGoreIdGetir(kisiBilgileri.f_name, kisiBilgileri.l_name);
AuthorPaperDetaylari.SaveAuthorPaperDetails(authorPaperDetay, userId); // save details via userId.
return userId;
}
This method saves personal information.
public static void SavePersonalInformations(KisiselBilgilerBal kisiBilgileri,string registrationCode,string conferenceName)
{
try
{
string cs = ConfigurationManager.AppSettings["SiteSqlServer"];
DBDataContext db = new DBDataContext(cs);
DBpersonalInformation personalInfo = new DBpersonalInformation();
personalInfo.f_name = kisiBilgileri.f_name;
personalInfo.l_name = kisiBilgileri.l_name;
personalInfo.university_affiliation = kisiBilgileri.university_affiliation;
personalInfo.department_name = kisiBilgileri.department_name;
personalInfo.address1 = kisiBilgileri.address1;
personalInfo.address2 = kisiBilgileri.address2;
personalInfo.city = kisiBilgileri.city;
personalInfo.state = kisiBilgileri.state;
personalInfo.zipCode = kisiBilgileri.zipCode;
personalInfo.country = kisiBilgileri.country;
personalInfo.phone = kisiBilgileri.phone;
personalInfo.email = kisiBilgileri.email;
personalInfo.orderId = kisiBilgileri.orderId;
personalInfo.registrationCode = registrationCode;
personalInfo.date = DateTime.Now;
personalInfo.conferenceName = conferenceName;
db.DBpersonalInformations.InsertOnSubmit(personalInfo);
db.SubmitChanges();
}
catch (Exception)
{
}
}
This method saves details
public static void SaveAuthorPaperDetails(AuthorPaperDetailsBal authorPaperDetay, int userId)
{
try
{
string cs = ConfigurationManager.AppSettings["SiteSqlServer"];
DBWebDataContext db = new DBWebDataContext(cs);
DBAuthorPaperDetail authorPaperDetail = new DBAuthorPaperDetail();
authorPaperDetail.paper_title = authorPaperDetay.paperTitleDetails;
authorPaperDetail.conference_maker_id = authorPaperDetay.confMakerId;
authorPaperDetail.additional_paper_title = authorPaperDetay.additionalPprTtle;
authorPaperDetail.areYouMainAuthor = authorPaperDetay.mainAuthor;
authorPaperDetail.feeForFirstAuthorPaper = authorPaperDetay.registerFeeForFirstAuthor;
authorPaperDetail.feeForAdditionalPaper = authorPaperDetay.regFeeForAdditionalPape;
authorPaperDetail.feeForParticipCoAuthors = authorPaperDetay.regFeeForCoAuthors;
authorPaperDetail.userId = userId;
authorPaperDetail.firstCoAuthorName = authorPaperDetay.firstCoAuthor;
authorPaperDetail.secondCoAuthorName = authorPaperDetay.secondCoAutho;
authorPaperDetail.thirdCoAuthorName = authorPaperDetay.thirdCoAuthor;
authorPaperDetail.toplamOdeme = authorPaperDetay.toplamMaliyet;
db.DBAuthorPaperDetails.InsertOnSubmit(authorPaperDetail);
db.SubmitChanges();
}
catch (Exception)
{
}
}
I don't know why it doesnt work. Any idea?
...
catch (Exception)
{
}
Well, that explains pretty much everything... don't do this. Ever. The database layer is trying to tell you what the problem is, and you are sticking your fingers in your ears, hoping that'll make it go away. If I had to guess: maybe an occasional timeout due to being blocked by another SPID.
If you can't do anything useful or appropriate with an exception, just let it bubble to the caller. If it gets to the UI, tell the user about it (or just log the issue internally and tell the user "There was a problem").
Also, a LINQ-to-SQL data-context is IDisposable; you should have using statement around db.
In addition to Marc's answer... You are calling SubmitChanges twice. If you want atomic data storage, you should call it once. You can use relational properties to create an object graph, and submit the whole graph at once.
public void SaveParentAndChildren()
{
using (CustomDataContext myDC = new CustomDataContext())
{
Parent p = new Parent();
Child c = new Child();
p.Children.Add(c);
myDC.Parents.InsertOnSubmit(p); //whole graph is now tracked by this data context
myDC.SubmitChanges(); // whole graph is now saved to database
// or nothing saved if an exception occurred.
} //myDC.Dispose is called for you here whether exception occurred or not
}

Categories

Resources