Update list object to database using InsertAllOnSubmit - c#

I'm trying to save changes to database using Linq 2 Sql, using InserAllOnSubmit method, it neither inserts the records nor throws errors/exceptions.
Please help me if I have done any mistake in the code.
Thanks in advance.
public void UpdateCoachingAssessmentInfo(CoachingAssessmentViewModel model)
{
Guid userGuid = model.UserGuid;
try
{
using (var ctxAdmin = new MemberDataContext(ConfigurationManager.ConnectionStrings[Constants.CONFIG_KEY_MEMBER_CONNECTION_STRING].ToString()))
{
List<CAT> userCat = new List<CAT>();
List<QandR> userQr = model.QuestionResponseIds;
foreach (var x in userQr)
{
CAT objCAT = new CAT();
objCAT.userGuid = model.UserGuid;
objCAT.Question_Id = x.QuestionId;
if (x.OptionId != null && x.OptionId != 0)
{
objCAT.Option_Id = x.OptionId;
objCAT.Option_Response = null;
}
else
{
objCAT.Option_Response = x.OptionResponse ?? null;
objCAT.Option_Id = null;
}
objCAT.createDate = DateTime.Now;
objCAT.updateDate = DateTime.Now;
userCat.Add(objCAT);
}
ctxAdmin.CATs.InsertAllOnSubmit(userCat);
}
UpdateCoachingAssessmentEligibility(userGuid);
}
catch (Exception ex)
{
throw new Exception("Unable to save changes to db.", ex);
}
}

You should add ctxAdmin.CATs.SubmitChanges() after ctxAdmin.CATs.InsertAllOnSubmit(userCat).
According to the documentation
The added entities will not be in query results until after SubmitChanges has been called.
Let me know if it helps.

Related

Trying to Add to Database: Collection was modified; enumeration operation may not execute?

Below is my controller That I am calling from a href button and passing an id. The href button is a duplicate button which is meant to create a copy of the selected module and add it to the database and then return it.
public ActionResult dupe(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
MODULE Modules = db.MODULE.Find(id);
if (Modules == null)
{
return HttpNotFound();
}
else
{
MODULE newMOd = new MODULE();
newMOd.APPLY__FINISH = Modules.APPLY__FINISH;
newMOd.CREATED_BY = Modules.CREATED_BY;
newMOd.CREATED_DATE = Modules.CREATED_DATE;
newMOd.MODULE_DESC = "Duplicate-"+Modules.MODULE_DESC;
newMOd.MODULE_TYPE = Modules.MODULE_TYPE;
newMOd.MODULE_TYPE1 = Modules.MODULE_TYPE1;
newMOd.PRODUCT_LINE = Modules.PRODUCT_LINE;
newMOd.MODULE_NAME = "Duplicate-" + Modules.MODULE_NAME;
foreach (MODULE_PARTS mp in Modules.MODULE_PARTS)
{
newMOd.MODULE_PARTS.Add(mp);
}
foreach (MODULE_OPTION mo in Modules.MODULE_OPTION)
{
MODULE_OPTION m = new MODULE_OPTION();
m.OPTION_NAME = mo.OPTION_NAME;
m.OPTION_TYPE = mo.OPTION_TYPE;
m.PRODUCT_LINE = mo.PRODUCT_LINE;
m.ADDED_BY = mo.ADDED_BY;
m.ADDED_ON = mo.ADDED_ON;
m.DEFAULT_FACTOR = mo.DEFAULT_FACTOR;
foreach (OPTION_PARTS op in mo.OPTION_PARTS)
{
m.OPTION_PARTS.Add(op);
}
newMOd.MODULE_OPTION.Add(mo);
}
newMOd.MODULE_PARTS = Modules.MODULE_PARTS;
newMOd.MODULE_OPTION = Modules.MODULE_OPTION;
db.MODULE.Add(newMOd);
db.SaveChanges();
}
return View(Modules);
}
This is my controller method, and when I try to add this module to database I get collection modified error. I'm not sure how or where?
enter image description here
The exception message in this case is quite clear... you cannot modify a member of a collection you are currently iterating over. It's that simple.

insert only new data instead duplicate the existing data

I have this code running calling the data from the core system,
public int MuatTurunMTS(hopesWcfRef.Manifest2 entParam, string destination, int capacity)
{
try
{
EL.iSeriesWcf.IiSeriesClient iClient = new iSeriesWcf.IiSeriesClient();
EL.iSeriesWcf.Manifest2 manifest2 = new iSeriesWcf.Manifest2();
manifest2 = iClient.GetManifest2(entParam.NOKT, destination, capacity);
DataTable dt = new DataTable();
dt = manifest2.Manifest2Table;
List<hopesWcfRef.Manifest2> LstManifest2 = new List<hopesWcfRef.Manifest2>();
for (int i = 0; i < dt.Rows.Count; i++)
{
hopesWcfRef.Manifest2 newDataRow = new hopesWcfRef.Manifest2();
newDataRow.NOPASPOT = dt.Rows[i][1].ToString();
newDataRow.NOKT = dt.Rows[i][0].ToString();
newDataRow.KOD_PGKT = dt.Rows[i][2].ToString();
newDataRow.KOD_KLGA = dt.Rows[i][3].ToString();
newDataRow.NAMA = dt.Rows[i][4].ToString();
newDataRow.TKHLAHIR = (dt.Rows[i][5].ToString() == "1/1/0001 12:00:00 AM" ? DateTime.Now : Convert.ToDateTime(dt.Rows[i][5])); //Convert.ToDateTime(dt.Rows[i][5]);
newDataRow.JANTINA = dt.Rows[i][6].ToString();
newDataRow.WARGANEGARA = dt.Rows[i][7].ToString();
newDataRow.JNS_JEMAAH = dt.Rows[i][8].ToString();
newDataRow.NO_SIRI = dt.Rows[i][9].ToString();
newDataRow.NO_MS = Convert.ToInt16(dt.Rows[i][10]);
newDataRow.BARKOD = dt.Rows[i][13].ToString();
newDataRow.NO_DAFTAR = dt.Rows[i][14].ToString();
//bydefault make cell empty
newDataRow.STS_JEMAAH = "";
newDataRow.SEAT_NO = "";
newDataRow.SEAT_ZONE = "";
newDataRow.BERAT = 0;
newDataRow.JUM_BEG = 0;
LstManifest2.Add(newDataRow);
}
int cntr = 0;
if (LstManifest2.Count != 0)
{
foreach (hopesWcfRef.Manifest2 manifest in LstManifest2)
{
cntr++;
SaveManifestTS(manifest);
}
}
return LstManifest2.Count;
}
catch (Exception ex)
{
throw ex;
}
}
And goes to :
public void SaveManifestTS(hopesWcfRef.Manifest2 manifest)
{
try
{
ent.BeginSaveChanges(SaveChangesOptions.Batch, null, null);
ent.AddObject("Manifest2", manifest);
ent.SaveChanges(SaveChangesOptions.Batch);
}
catch (Exception ex)
{
//Uri u = new Uri(ent.BaseUri + "GetErrorMsg"
// , UriKind.RelativeOrAbsolute);
//string datas = (ent.Execute<string>(u)).FirstOrDefault();
//Exception ex = new Exception(datas);
throw ex;
}
}
When SaveChanges run, if the data exist it will duplicate the entire row,
How to avoid the data being duplicate when insert (savechanges)??????
Many Thanks
What about: Do not insert.
In these cases I am using a MERGE statement that updates existing data (based on primary key) and inserts new data.
Oh, and all the code example you loved to post is totally irrelevant to the question, which is a pure SQL side question. You literally quote your car manual then asking which direction to turn.

How can I pass a function with one parameter to an ICommand?

Here's my ICommand:
public ICommand ConfirmLotSavedCommand {
get
{
return new RelayCommand(ConfirmLotSaved);
}
}
The problem is I have deserialized data that I want to store into database after a user clicks confirm button. If the user does not click on confirm or the lot number already exists, then I don't want to save the deserialized string in db.
I had trouble calling a function with one parameter inside my ConfirmLotSaved() method because of scope.
So I created a set the deserialized lot as a field and put the code to save to db inside of ConfirmLotSaved(). However, the field is null for some strange reason... I'm not sure why.
Here's my attempt:
private LotInformation lot; //field that is supposed to contain all the deserialized info
private void ConfirmLotSaved()
{
using (var db = new DDataContext())
{
bool lotNumDbExists = db.LotInformation.Any(r => r.lot_number == DeserialLotNumber);
if (lotNumDbExists == false)
{
successWindow.Message = "Successfully Saved Lot";
dialogService.ShowDialog(successWindow.Message, successWindow);
LotInformation newLot = new LotInformation();
if (newLot != null)
{
newLot.Id = lot.Id;
newLot.lot_number = lot.lot_number;
newLot.exp_date = lot.exp_date;
LotNumber = Lot.lot_number;
ExpirationDate = Lot.exp_date.ToString();
foreach (Components comp in lot.Components)
{
newLot.Components.Add(comp);
}
ComponentsList = newLot.Components;
foreach (Families fam in lot.Families)
{
newLot.Families.Add(fam);
}
FamiliesList = newLot.Families;
try
{
db.LotInformation.Add(newLot);
db.SaveChanges();
//Grabs the lot_number column from db that is distinct
var lotNum = db.LotInformation.GroupBy(i => i.lot_number).Select(group => group.FirstOrDefault());
//Loops through the lot numbers column in db and converts to list
foreach (var item in lotNum)
{
Console.WriteLine(item.lot_number);
}
LotNumList = lotNum.ToList();
Console.WriteLine("successfully");
}
catch
{
//TODO: Add a Dialog Here
}
}
else if (lotNumDbExists == true)
{
// Inform user that the lot_number already exists
errorWindow.Message = LanguageResources.Resource.Lot_Exists_Already;
dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
logger.writeErrLog(LanguageResources.Resource.Lot_Exists_Already);
return;
}
}
}
}
Deserialization function to see where lot is grabbing data:
public void DeserializedStream(string filePath)
{
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "lot_information";
xRoot.IsNullable = false;
// Create an instance of lotinformation class.
LotInformation 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();
LotInformation newList = new LotInformation();
using (var db = new DDataContext())
{
bool isDuplicate = db.LotInformation.Any(r => r.lot_number == lot.lot_number);
if (newList != null && isDuplicate == false)
{
newList.Id = lot.Id;
newList.lot_number = lot.lot_number;
newList.exp_date = lot.exp_date;
DeserialLotNumber = newList.lot_number;
DeserialExpirationDate = newList.exp_date.ToString();
foreach (Component comp in lot.Components)
{
newList.Components.Add(comp);
}
DeserialComponentsList = newList.Components;
foreach (Families fam in lot.Families)
{
newList.Families.Add(fam);
}
DeserialFamiliesList = newList.Families;
}
else if (isDuplicate == true)
{
DeserialAnalytesList = null;
DeserialFamiliesList = null;
// Inform user that the lot_number already exists
errorWindow.Message = LanguageResources.Resource.Lot_Exists_Already;
dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
logger.writeErrLog(LanguageResources.Resource.Lot_Exists_Already);
return;
}
}
}
I figured out what was wrong:
After setting private LotInformation lot; field before constructor, I redeclared locally my mistake:
LotInformation lot = new LotInformation();
Changed it to:
lot = new LotInformation();
and it works.
I suggest you to use RelayCommand's generic edition http://www.kellydun.com/wpf-relaycommand-with-parameter/
It will allow you to pass lot to your command from view, all you need to store lot in current DataContext.

How to update a table which has a foreign key reference using Entity Framework?

I have the following method:
public static Int32 SaveAgent(IAgent i)
{
dc = new mcollectorDataContext(ConnectionString.GetConStr());
//check if the record exists
t_agent matchID = dc.t_agents.Where(x => x.id == i.AgentID).FirstOrDefault();
try
{
if (matchID == null)
{
// if not exists add new row
t_agent _agent = new t_agent
{
wallet = i.Wallet,
branchid = GetBranchID(i.Branch),
lastupdated = i.LastUpdated,
};
dc.t_agents.InsertOnSubmit(_agent);
dc.SubmitChanges();
return _agent.id;
}
else
{
// else update row
matchID.wallet = i.Wallet;
matchID.branchid = GetBranchID(i.Branch);
matchID.lastupdated = i.LastUpdated;
dc.SubmitChanges();
return i.AgentID;
}
}
catch (Exception)
{
throw ;
}
}
This method save new reord but when i try to update, it failed, no record can be updated, but it does not throw also an error.
How can fix that problem ??
maybe try telling entity framework that the model has been modified?
try adding this before calling submitchanges
dc.Entry(matchID).State = EntityState.Modified;

Insert data into database using LINQ

I wrote a very simple method. It saves data from class DayWeather to the database. Method checks if line with that day exist in table and update her or create a new line.
I am doing it by adding new class for LINQ and move table from Server Inspector to the constructor. It generate new class WeatherTBL.
Method itself looks like this:
public static void SaveDayWeather(DayWeather day)
{
using (DataClassesDataContext db = new DataClassesDataContext())
{
var existingDay =
(from d in db.WeatherTBL
where d.DateTime.ToString() == day.Date.ToString()
select d).SingleOrDefault<WeatherTBL>();
if (existingDay != null)
{
existingDay.Temp = day.Temp;
existingDay.WindSpeed = day.WindSpeed;
existingDay.Pressure = day.Pressure;
existingDay.Humidity = day.Humidity;
existingDay.Cloudiness = day.Cloudiness;
existingDay.TypeRecip = day.TypeRecip;
db.SubmitChanges();
}
else
{
WeatherTBL newDay = new WeatherTBL();
newDay.DateTime = day.Date;
newDay.Temp = day.Temp;
newDay.WindSpeed = day.WindSpeed;
newDay.Pressure = day.Pressure;
newDay.Humidity = day.Humidity;
newDay.Cloudiness = day.Cloudiness;
newDay.TypeRecip = day.TypeRecip;
db.WeatherTBL.InsertOnSubmit(newDay);
db.SubmitChanges();
}
}
}
When I tried to call him from UnitTest project:
[TestMethod]
public void TestDataAccess()
{
DayWeather day = new DayWeather(DateTime.Now);
DataAccessClass.SaveDayWeather(day);
}
It write, that test has passed successfully. But if look into table, it has`t chanched.
No error messages shows. Does anyone know whats the problem?
P.S. Sorry for my bad English.
UDP
Problem was in that:
"...db maybe copied to the debug or release folder at every build, overwriting your modified one". Thanks #Silvermind
I wrote simple method to save employee details into Database.
private void AddNewEmployee()
{
using (DataContext objDataContext = new DataContext())
{
Employee objEmp = new Employee();
// fields to be insert
objEmp.EmployeeName = "John";
objEmp.EmployeeAge = 21;
objEmp.EmployeeDesc = "Designer";
objEmp.EmployeeAddress = "Northampton";
objDataContext.Employees.InsertOnSubmit(objEmp);
// executes the commands to implement the changes to the database
objDataContext.SubmitChanges();
}
}
Please try with lambda expression. In your code, var existingDay is of type IQueryable
In order to insert or update, you need a variable var existingDay of WeatherTBL type.
Hence try using below..
var existingDay =
db.WeatherTBL.SingleOrDefault(d => d.DateTime.Equals(day.Date.ToString()));
if(existingDay != null)
{
//so on...
}
Hope it should work..
Linq to SQL
Detail tc = new Detail();
tc.Name = txtName.Text;
tc.Contact = "92"+txtMobile.Text;
tc.Segment = txtSegment.Text;
var datetime = DateTime.Now;
tc.Datetime = datetime;
tc.RaisedBy = Global.Username;
dc.Details.InsertOnSubmit(tc);
try
{
dc.SubmitChanges();
MessageBox.Show("Record inserted successfully!");
txtName.Text = "";
txtSegment.Text = "";
txtMobile.Text = "";
}
catch (Exception ex)
{
MessageBox.Show("Record inserted Failed!");
}

Categories