EntityFramework error when trigger SaveChangesAsync() - c#

Got an error stated
Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.
when I trigger SaveChangesAsync() function. See my code below:
using (var context = new CommonDBContext()) {
var bbrs = await context.Table1
.ToListAsync();
var lastIndexToRemove = pimc.Result.IndexOf("UIX/");
if (lastIndexToRemove > -1)
{
bbrPimcStr = pimc.Result.Remove(0, lastIndexToRemove);
}
foreach (var bbr in bbrs) {
bbr.XBBR = xbbrStr;
bbr.LastUpdated = DateTime.Now;
bbr.LastUpdatedBy = userId;
if (!pimc.HasError)
{
var graveDKI = context.graveDKIStore
.Where(x => x.RefId == bbr.Id)
.FirstOrDefault();
if (graveDKI != null)
graveDKI.GraveDKI = bbrPimcStr ;
else
context.graveDKIStore.Add(new graveDKIStore
{
Id = Guid.NewGuid(),
GraveDKI = bbrPimcStr ,
RefId = bbr.Id,
MsgType = "PPIXFFT"
});
}
}
return await context.SaveChangesAsync(); // Got issue here
Can someone tell me whats wrong with my code? thanks.
Update: Added exception stack.

I fixed the issue by checking the length of the character, it might be different errors base on what data annotation or validator annotation that you placed on your object. To double check if your validations are correct, you can check through exception stack under EntityValidationErrors to get more in-depth information about it, see image below.
public class GraveDKIStore {
...
[MaxLength(5)] // The issue is here so I changed it to 10.
public string MsgType { get; set; }
...
}
P.S. thanks to Roman Doskoch for a very helpful advice.

Related

Elasticsearch while doing update operation , to select that particular index getting exception

In am new in elasticsearch and i am trying to do update operation with elasticsearch but for that when am trying to filter and select that particular code i am getting execption and the exception is:
An exception of type 'ElasticsearchCRUD.ElasticsearchCrudException' occurred in ElasticsearchCRUD.dll but was not handled in user code,
Additional information: ElasticSearchContextGet: HttpStatusCode.BadRequestNo handler found for uri [//skillwithlistofdetailss/skillwithlistofdetails/1] and method [GET]
and my method is below:
public void UpdateSkill(long updateId, string updateName, string updateDescription, List<SkillDetail> updateSkillDetailsList)
{
using (var context = new ElasticsearchContext(ConnectionString, _elasticSearchMappingResolver))
{
//var addressItem = _elasticsearchContext.SearchById<SkillWithListOfDetails>(updateId);
//var entityAddress = _entityFrameworkContext.Address.First(t => t.Id == addressItem.Id);
try
{
var skill = context.GetDocument<SkillWithListOfDetails>(updateId);
skill.Updated = DateTime.UtcNow;
skill.Name = updateName;
skill.Description = updateDescription;
skill.SkillDetails = updateSkillDetailsList;
foreach (var item in skill.SkillDetails)
{
item.Updated = DateTime.UtcNow;
}
context.AddUpdateDocument(skill, skill.Id);
context.SaveChanges();
}
catch(Exception e)
{
throw e;
}
}
}
and i am getting exception in this line of code:--
var skill = context.GetDocument(updateId);
There seems to be a problem with index/type name somewhere? The error message says: "ElasticSearchContextGet: HttpStatusCode.BadRequestNo handler found for uri [//skillwithlistofdetailss/skillwithlistofdetails/1] and method [GET]:".
Check your index and type are correct or not.
Index: skillwithlistofdetailss
Type: skillwithlistofdetails

Entity Framework 5 : One to Many with foreignKey Updated/Added/Deleted

When I update my member, I want to update his BankCheck too.
This is my database:
My bankCheck can be added, updated or deleted.
My member can be updated only (name, surname...)
I choose my member in my datagrid, and select Edit, my wpf app switch to an other page and display my member with Textbox etc.
I click on my button to add/edit/delete his bankCheck and I can edit the first bankCheck.
I delete the last bankCheck and I add an other (for example).
I press OK and I click on "Valid my Edit".
My program re-creates a new Member with his bankCheck and i made this:
private void EditMember(Member updatedMember)
{
try
{
using (var context = new KravMagaEntities())
{
context.Member.Attach(updatedMember);
context.Entry(updatedMember).State = EntityState.Modified;
context.SaveChanges();
}
ResetAllControls();
States.EnumToText(States.StatesEnum.UpdatingSuccess);
Application.Current.Dispatcher.Invoke(() =>
{
_managementService.IsVisibleAddTab(true);
_managementService.IsVisibleEditTab(false);
});
}
catch (Exception exception)
{
States.EnumToText(States.StatesEnum.Error, exception);
}
}
But I have this error:
A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.
I don't know how I can fix this error.
Thank you.
My code:
private void OnEditMemberBtnClicked(object sender, RoutedEventArgs e)
{
try
{
var isValidateCertificat = IsValidDate(BirthDateTxt);
var isValidateBirth = IsValidDate(CertificateDateTxt);
var isValidateAutorisation = IsValidDate(AutorizationDateTxt);
var isValidateReglement = IsValidDate(RuleDateTxt);
if (isValidateBirth && isValidateCertificat && isValidateAutorisation && isValidateReglement)
{
States.EnumToText(States.StatesEnum.Updating);
var typePaiement = BankCheckRadio.IsChecked.Value;
var typePaiementText = typePaiement ? "Chèque" : "Espèce";
var doctor = "";
var dateCertificate = "";
if (BankCheckRadio.IsChecked.Value)
{
doctor = DoctorTxt.Text;
dateCertificate = CertificateDateTxt.Text;
}
var editedMember = new Member
{
id_Member = _idForEdit,
name_Member = UppercaseChar(NameTxt.Text),
surname_Member = UppercaseChar(SurnameTxt.Text),
birthDate_Member = BirthDateTxt.Text,
autorizationDate_Member = AutorizationDateTxt.Text,
address_Member = UppercaseChar(AddressTxt.Text),
postalCode_Member = PostalCodeTxt.Text,
country_Member = UppercaseChar(CountryTxt.Text),
fixPhone_Member = FixPhoneTxt.Text,
mobilePhone_Member = MobilePhoneTxt.Text,
mail_Member = MailTxt.Text,
beginDate_Member = BeginDateCombo.Text,
ruleDate_Member = RuleDateTxt.Text,
subscription_Member = SubscriptionCombo.Text,
typePaiement_Member = typePaiement,
typePaiementText_Member = typePaiementText,
federationNumero_Member = FederationNumeroTxt.Text.ToUpper(),
level_Member = LevelCombo.Text,
certificate_Member = CertificateCheckbox.IsChecked.Value,
doctor_Member = UppercaseChar(doctor),
certificateDate_Member = dateCertificate,
problem_Member = UppercaseChar(ProblemTxt.Text, true),
emergencyName_Member = UppercaseChar(EmergencyNameTxt.Text),
emergencyPhone_Member = EmergencyPhoneTxt.Text,
BankCheck = _bankChecks
};
if (_bankChecks != null)
{
using (var context = new KravMagaEntities())
{
foreach (var bankCheck in _bankChecks)
{
bankCheck.idMember_BankCheck = editedMember.id_Member;
context.Entry(bankCheck).State = EntityState.Added;
}
context.SaveChanges();
}
}
new Task(() => EditMember(editedMember)).Start();
}
}
catch (Exception exception)
{
States.EnumToText(States.StatesEnum.Error, exception);
}
}
So as I see, you're updating only Member, not all the modified BankAccounts. You're updating navigation property of entities from both sides but calling SaveChanges() only on entity from one side. So your Member starts to refer another BankAccount while your BankAccounts still refer to the old Member. You need to mark all appropriate BankAccounts as modified along with your modified Member in the same place and then call SaveChanges() so everything will be saved (from comment).
To prevent adding a duplicate you can try to set the state of your entities to the State.Modified instead of State.Added.
The reason of that problem was that you were updating only entity from one side. If you have BankAccounts-Members relationship then in case you update the navtigation property for Member you should update a navigation property for BankAccount too and vice versa. If you just update some property (Member.Name or anything) you just set this Member's State to State.Modified without affecting any of other Member's, BankAccount's etc.
If the entity tracking is turned on for you then EF will automatically track entities that were modified and set appropriate states for them. But as I've seen from your issue, it's turned off for you so you have to manually set the state for each object you want to add/update/delete.

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
}

Out of Memory at line XXXX

can anyone help me how to resolve the out of memory error on my asp page? im using linq to sql.. after adding data several data.. like more than 10 rows. in the grid. an out of memory error occurs.. attached herewith is my add function..
public ServiceDetail checkservicedetailid()
{
string ServiceName = ViewState["Tab"].ToString();
ServiceDetail checkservicedetailid = ServiceDetails_worker.get(a => a.ServiceName == ServiceName && a.MarginAnalysisID == checkmarginanalysisid().MarginAnalysisID).SingleOrDefault();
return checkservicedetailid;
}
public IEnumerable<ServiceDetail> get(Expression<Func<ServiceDetail, Boolean>> express)
{
return ServiceDetailsDB.ServiceDetails.Where(express);
}
protected void btnSaveEmptyOC_Click(object sender, EventArgs e)
{
try
{
if (checkservicedetailid() != null)
{
CashExpense tblCashExpenses = new CashExpense();
Guid CashExpensesID = Guid.NewGuid();
tblCashExpenses.CashExpensesID = CashExpensesID;
tblCashExpenses.ServiceDetailsID = checkservicedetailid().ServiceDetailsID;
tblCashExpenses.Description = txtDescriptionEmptyOC.Text;
tblCashExpenses.Quantity = Decimal.Parse(txtQTYEmptyOC.Text);
tblCashExpenses.UnitCost = Decimal.Parse(txtUnitCostEmptyOC.Text);
tblCashExpenses.CreatedBy = User.Identity.Name;
tblCashExpenses.DateCreated = DateTime.Now;
tblCashExpenses.CashExpensesTypeID = "OTHER";
CashExpenses_worker.insert(tblCashExpenses);
CashExpenses_worker.submit();
//Clear items after saving
txtDescriptionEmptyOC.Text = "";
txtQTYEmptyOC.Text = "";
txtUnitCostEmptyOC.Text = "";
ValidationMessage.ShowValidationMessage(MessageCenter.CashExpenseMaintenace.InsertOC2, "SaveEmptyOC", this.Page);
MyAuditProvider.Insert(this.GetType().ToString(), ViewState["MarginAnalysisID"].ToString(), MessageCenter.Mode.ADD, MessageCenter.CashExpenseMaintenace.InsertOC2, Page.Request, User);
divOtherCost.Visible = false;
grd_othercost.Visible = true;
btnaddothercost.Visible = true;
}
else
{
//Displays a Message on the Validation Summary (Service Id does not exist)
ValidationMessage.ShowValidationMessage(MessageCenter.CashExpenseMaintenace.SaveServiceDetailOC, "SaveEmptyOC", this.Page);
}
}
catch
{
//Displays a Message on the Validation Summary (Error on Saving)
ValidationMessage.ShowValidationMessage(MessageCenter.CashExpenseMaintenace.InsertOCError, "SaveEmptyOC", this.Page);
}
finally
{
//Rebinds the Grid
populategrd_othercost();
}
}
I'm guessing from your code here:
ServiceDetail checkservicedetailid = ServiceDetails_worker.get(
a => a.ServiceName == ServiceName &&
a.MarginAnalysisID == checkmarginanalysisid().MarginAnalysisID
).SingleOrDefault();
that .get() is taking a Func<SomeType, bool>, and you are doing something like:
var row = dbCtx.SomeTable.Where(predicate);
(please correct me here if I'm incorrect)
This, however, is using LINQ-to-Objects, meaning: it is loading every row from the table to the client and testing locally. That'll hurt memory, especially if a different db-context is created for each row. Additionally, the checkmarginanalysisid() call is being executed per row, when presumably it doesn't change between rows.
You should be testing this with an Expression<Func<SomeType, bool>> which would be translated to TSQL and executed at the server. You may also need to remove untranslatable methods, i.e.
var marginAnalysisId = checkmarginanalysisid().MarginAnalysisID;
ServiceDetail checkservicedetailid = ServiceDetails_worker.get(
a => a.ServiceName == ServiceName &&
a.MarginAnalysisID == marginAnalysisId
).SingleOrDefault();
where that is get(Expression<Func<SomeType, bool>>).
I tried all of the solution given to me both by my peers as well as the solution provided here, from GC.Collect, to disposing linq datacontext after use etc. however the error keeps on occurring, i then tried to remove the update panel, Ive read a site that showed how ridiculous update panel when it comes to handling data esp when a function is done repeatedly. And poof! the memory problem is gone!

Categories

Resources