Entity framework different contexts exception within Asp.net application - c#

I'm new in the use of Entity Framework and i have this problem :
List<Metier> listofjobs = new List<Metier>();
Guid userId;
WorkEntities notrecontexte;
Candidat CurrentCandidat;
protected void Page_Load(object sender, EventArgs e)
{
userId = new Guid(Membership.GetUser().ProviderUserKey.ToString());
notrecontexte = new WorkEntities ();
CurrentCandidat = notrecontexte.Candidat
.Include("Metier1")
.Include("Mobilite1")
.Include("NiveauDuDiplome1")
.Include("NiveauDuPoste1")
.Include("Disponibilite_Candidat")
.Include("Contrats1")
.First(x => x.UserId.Equals(userId) == true);
}
protected void btn_Click(object sender, EventArgs e)
{
listofjobs = (List<Metier>)Session["listofjobs"];
if (listofjobs != null)
{
CurrentCandidat.Metier1.Clear();
try
{
notrecontexte.SaveChanges();
}
catch { }
for (int i = 0; i < listofjobs.Count; i++)
{
CurrentCandidat.Metier1.Add(listofjobs[i]);
try
{
notrecontexte.SaveChanges();
}
catch { }
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
if ((List<Metier>)Session["listofjobs"] != null)
{
listofjobs = (List<Metier>)Session["listofjobs"];
}
string newjob = tbAddMetier.Text;
Metier m = new Metier { Lebelle = newjob };
tbAddMetier.Text = "";
listofjobs.Add(m);
rptrMetier.DataSource = listofjobs;
rptrMetier.DataBind();
C_Compte.Update();
Session["listofjobs"] = listofjobs;
}
protected void ImageButton1_Click(object sender, CommandEventArgs e)
{
if ((List<Metier>)Session["listofjobs"] != null)
{
listofjobs = (List<Metier>)Session["listofjobs"];
}
string newjob = e.CommandArgument.ToString().Split(',')[0];
listofjobs.Remove(listofjobs.Find(x => x.Lebelle == newjob));
rptrMetier.DataSource = listofjobs;
rptrMetier.DataBind();
C_Compte.Update();
Session["listofjobs"] = listofjobs;
}
I have problem in these lines :
CurrentCandidat.Metier1.Add(listofjobs[i]);
try
{
notrecontexte.SaveChanges();
}
catch { }
when i try to save the changes i got this exception The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects. .
What are the reasons of this exception?
How can i fix it?

Entity Framework has a context dependent behaviour. If an entity belongs to an instance of a context, you cannot use it in another instance of context unless you detach the entity from the first context and attach to the second.
For your case, at the point where you save your list of entities to the session, you need to detach the list first, and at the button click event, you need to attach listofJobs to the your current context.
I am not clear about your program flow but, if you can attach the list right after every listofjobs = (List<Metier>)Session["listofjobs"]; and detach right before every Session["listofjobs"] = listofjobs; that might work.
You can see how to detach and attach objects in Entity framework you can use links below:
http://msdn.microsoft.com/en-us/library/vstudio/bb896271(v=vs.100).aspx
http://msdn.microsoft.com/en-us/library/vstudio/bb896245(v=vs.100).aspx
http://msdn.microsoft.com/en-us/library/vstudio/bb738697(v=vs.100).aspx

Related

Fetching 1 record based on the name of the logged in User and show these values in txt boxes (c#)

I Want to fetch 1 record based on the name of the logged in User and show these values in txt boxes (c#)
I am a bit stuck on how to handle this, any help would be welcome.
Currently I am trying to fetch it using LINQ:
DAL.VindjekindjeDataContext dc = new DAL.VindjekindjeDataContext();
public object GetCompleteOuder(string p)
{
//var query = (from TOUD in dc.TOUDs where TOUD.Ouderid == p select TOUD).Single();
return (from TOUD in dc.TOUDs where TOUD.Voornaam.Equals(p) select TOUD ).First();
}
protected void Page_Load(object sender, EventArgs e)
{
string naam = User.Identity.Name;
object parent = new object();
parent = Ouder.GetCompleteOuder(naam);
Type typB = parent.GetType();
NaamTxt.Text = (string)typB.GetField("Naam").GetValue(parent);
}
However I get the following error:
System.NullReferenceException: Object reference not set to an instance of an object.
There is just too much going wrong here.
Your exception is possibly caused by a parent (ouder in Dutch) which has a null value for Voornaam)
You instantiate an object parent which is useless since you overwrite it the next line.
Your parent variable should be strongly typed. That will prevent you to need reflection to get the Naam property. This, by the way, is another possible source for your NullReferenceException.
Perhaps something like this
public bool GetCompleteOuder(out TOUD user, string p)
{
user = new TOUD();
try
{
db.TOUDS.SingleOrDefault(t => t.Voornaam == p);
return true;
}
catch
{
return false;
}
}
protected void Page_Load(object sender, EventArgs e)
{
string naam = User.Identity.Name;
TOUD user;
if(GetCompleteOuder(out user, naam))
{
NaamTxt.Text = user.<fieldname>;
}
else
{
NaamTxt.Text = string.empty;
}
}
Final working code:
DAL.VindjekindjeDataContext dc = new DAL.VindjekindjeDataContext();
public bool GetCompleteOuder(out DAL.TOUD user, string p)
{
user = new DAL.TOUD();
try
{
dc.TOUDs.SingleOrDefault(t => t.Voornaam == p);
user = (from TOUD in dc.TOUDs where TOUD.Voornaam.Equals(p) select TOUD).Single();
return true;
}
catch
{
return false;
}
}
//page load behind aspx page
OuderDAL Ouder = new OuderDAL();
protected void Page_Load(object sender, EventArgs e)
{
string naam = User.Identity.Name;
DAL.TOUD user;
if(Ouder.GetCompleteOuder(out user, naam))
{
/*vullen van de velden met de gegevens voor de ingelogde gebruiker*/
NaamTxt.Text = user.Naam;

How to override a session

I have a question can I overwrite a session that I allredy have set (I set the the user specific department)
Session:
int depId = user.HtDepartments.FirstOrDefault().DepartmentId;
Session["DepId"] = depId;
I want to override this id that I saved in the session with a new "id" that the user selectes out of the RadComboBox.
So when the user is coming back to this page not his "pre selected" department is selected , selected is the new department that he slected before
My code so far:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.Page.IsPostBack)
{
this.parameterDepId = this.Request["depId"];
if (string.IsNullOrEmpty(parameterDepId))
{
parameterDepId = Session["depId"].ToString();
}
this.LoadDE(parameterDepId);
this.UserGrid.DataBind();
}
}
Loading the session
Here how I load my department
protected void LoadDE(string depId)
{
IEnumerable<HtDepartment> departments = null;
if (this.selectedBu != null)
{
departments = this.selectedBu.HtDepartments;
}
this.rcbDepartments.DataTextField = "Name";
this.rcbDepartments.DataValueField = "DepartmentId";
this.rcbDepartments.DataSource = departments;
this.rcbDepartments.DataBind();
this.rcbDepartments.Items.Insert(0, new RadComboBoxItem("-All-"));
if (depId != null)
{
int index = this.rcbDepartments.Items.IndexOf(this.rcbDepartments.Items.Where(i => i.Value == depId).SingleOrDefault());
if (index > -1)
{
this.rcbDepartments.Items[index].Selected = true;
this.selectedDepartment = departments.Where(i => i.DepartmentId == int.Parse(depId)).SingleOrDefault();
}
}
}
protected void rcbDepatments_SelectedIndexChanged(object sender, RadComboBoxSelectedIndexChangedEventArgs e)
{
if (this.rcbDepartments.Items.Count > 1 && this.rcbDepartments.SelectedIndex > 0)
{
this.selectedDepartment = HtDepartment.GetById(int.Parse(e.Value));
parameterDepId = this.selectedDepartment.ToString();
}
else
{
this.selectedDepartment = null;
}
this.dataSourceFilterChanged();
}
A resume of my question:
How and where should I override my session in the load method or in SelectedIndexChanged ?
It makes sense to check for the saved variable when loading a page, as the user won't be able to interact with the controls until this method has completed.
private void OnLoad(object sender, EventArgs e)
{
this.parameterDepId = this.Request["depId"];
}
But to override it with a new value you simply set a new value. Then the next time you loaded the page this newly set value would be returned in the OnLoad method.
private void MyControl_SelectedIndexChanged(object sender, EventArgs e)
{
Session["DepId"] = MyControl.SelectedValue;
}
I'm finding your question a bit unclear but hopefully this answers the main point of it and helps with your code logic.

Reloading and Updating using Entity Framework and DBContext

Ok so I have tried a few things and keep getting stuck. I had the update button working at one point and now it will not update. The delete button will work and delete records but I can not get the gridview to refresh after the record is deleted. I also want the gridview to reload after the update button is pressed and the record is updated. Here is what I have:
protected void btnDelete_Click(object sender, EventArgs e)
{
switch (btnDelete.Text)
{
case DeleteButton:
try
{
if (txtLocationName.Text != null && txtSubAccountName.Text != null)
{
Location locationCheck = _context.Locations.ToList()
.First(x => x.Name == txtLocationName.Text && x.SubAccount == txtSubAccountName.Text);
if (locationCheck != null)
{
Location n = new Location
{
Id = grdvwLocationList.SelectedIndex,
Name = txtLocationName.Text,
SubAccount = txtSubAccountName.Text
};
_context.Locations.Remove(n);
_context.SaveChanges();
}
}
}
catch (Exception)
{
lblLocationNameNotification.Text = "Please type in a location/sub-account or select a location/sub-account that doesn't have a asset to delete.";
txtLocationName.Text = "";
txtSubAccountName.Text = "";
}
break;
case CancelButton:
Reload();
break;
}
}
public void PopulateLocationGridView()
{
var locations = _context.Locations.Where(l => l.CompanyId == CompanyId)
.OrderBy(l => l.Name)
.ToList();
grdvwLocationList.DataSource = locations;
grdvwLocationList.DataBind();
if (locations.Count > 0)
{
grdvwLocationList.SelectedIndex = 0;
RowSelected();
}
else
{
txtLocationName.Text = "";
txtSubAccountName.Text = "";
}
}
The add button works just fine it just seems to be refreshing the grid view
I have the following exampe working in a winforms application
The trick is the dset.local
private void Form1_Load(object sender, EventArgs e)
{
var dset = Db.Tasks; // Db is my context.
DbSet<Task> qry = dset;
qry.Load();
bindingSource1.DataSource =dset.Local.ToBindingList();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
Debug.Print(Db.Tasks.Count().ToString());
bindingSource1.EndEdit();
Db.SaveChanges();
}
After working on it last night I knew there was something that I was missing. I ended up going about it like this:
protected void btnDelete_Click(object sender, EventArgs e)
{
try
{
_context = new IMSDBContext();
switch (btnDelete.Text)
{
case DeleteButton:
if (txtLocationName.Text != null && txtSubAccountName.Text != null)
{
Location location = _context.Locations.ToList()
.First(x => x.Name == txtLocationName.Text && x.SubAccount == txtSubAccountName.Text);
_context.Locations.Remove(location);
_context.SaveChanges();
PopulateLocationGridView();
grdvwLocationList.SelectedIndex = 0;
RowSelected();
}
break;
case CancelButton:
Reload();
break;
}
}
catch (Exception ex)
{
lblLocationNameNotification.Text = ex.Message;
}
finally
{
if (_context != null)
{
_context.Dispose();
}
}
}
I had tried to use the PopulateLocationGridView() and RowSelect() methods by themselves and it was still having trouble. I ended up putting in the grdvwLocationList.SelectedIndex = 0; in to set the selected index on the first index in the list instead of the index of the record that I just deleted. That is where I was having trouble. I thought that the SelectRow() would reselect the index again but I had to reset it back to another index. If there are any questions or comments please feel free. I am still learning and would like all of the advise that I can get.

Linq update query

I want to update an existing record. I also have debugged my code. The int id variable gets the value, but I don't know why my record doesn't updated.
SQLDBDataClassesDataContext dContext = new SQLDBDataClassesDataContext();
protected void Page_Load(object sender, EventArgs e)
{
//if (!IsPostBack)
{
if (!string.IsNullOrEmpty(Request.QueryString["fname"]))
{
FirstNameTextBox.Text = Request.QueryString["fname"];
}
if (!string.IsNullOrEmpty(Request.QueryString["lname"]))
{
LastNameTextBox.Text = Request.QueryString["lname"];
}
if (!string.IsNullOrEmpty(Request.QueryString["cellnum"]))
{
CellNumberTextBox.Text = Request.QueryString["cellnum"];
}
}
}
protected void UpdateButton_Click(object sender, EventArgs e)
{
int id = Convert.ToInt32(Request.QueryString["id"]);
var updatequery1 = dContext.PersonalDetailTables
.Where(pd => pd.ID == id).SingleOrDefault();
if (updatequery1 != null)
{
updatequery1.FirstName = FirstNameTextBox.Text;
updatequery1.LastName = LastNameTextBox.Text;
updatequery1.CellNumber = CellNumberTextBox.Text;
dContext.SubmitChanges();
}
}
if (updatequery1 != null)
is updatequery1 null? If it's now, it'll just skip right over. Setup a breakpoint and step through.
Alternatively, change .SingleOrDefautl to .Single instead. This way if nothing's found, u'll get an exception, and u'll know what's up.
Call dContext.InsertOnSubmit(fooentity) method before calling dContext.SubmitChanges();.
For example.
var ctx = DB.fooDB;
fooobj.fooName= bar.fooName;
fooobj.fooID= bar.fooID;
if (fooobj.fooID== 0)
ctx.Locations.InsertOnSubmit(bar);
ctx.SubmitChanges();
I`ve got my Solution..
the only problem was of if(!ispostback) issue.
context.InvProductStockMasters
.Update(ps => ps.LocationID.Equals(invStockAdjustmentHeader.LocationID)
&& ps.ProductID.Equals(invStockAdjustmentDetail.ProductID),
ps => new InvProductStockMaster
{ Stock = ps.Stock - invStockAdjustmentDetail.OrderQty });

objects in datagridview

Im adding objects to a datagridview ( only one kind) through a list
ej.
List<Material> mater = new List<Material>();
DataGridView dgvMAterial = new DataGridView();
dgvMaterial.DataSource = null;
mater.Add((Material)cmbMaterial.SelectedValue);
dgvMaterial.DataSource = mater;
But every time I click over the datagrid I get an indexoutofrangeexeption.
Can somone tell me why?
thanks
here is my whole code for the form
public partial class inicio : Form
{
private string ConnectionString = "Data Source=localhost\\sqlexpress;Initial Catalog=data.mdf;Integrated Security=SSPI;";
//private string ConnectionString = "Server=.\\SQLExpress;AttachDbFilename=|DataDirectory|\\data\\data_data.mdf.mdf; Database=data.mdf;Trusted_Connection=Yes;";
private ISessionFactory sessionFactory;
List<Material> mater = new List<Material>();
List<Salarios> salar = new List<Salarios>();
IBindingList mind = new BindingList<Salarios>();
Productos prod;
public inicio()
{
InitializeComponent();
sessionFactory = nhn.BusinessObjects.Initialize.CreateSessionFactory(ConnectionString);
dgvMaterial.DataSource = mater;
}
private void materialToolStripMenuItem_Click(object sender, EventArgs e)
{
Catalogos.frmMaterial material = new costeos.Catalogos.frmMaterial(ConnectionString);
material.ShowDialog(this);
material.Dispose();
}
private void salariosToolStripMenuItem_Click(object sender, EventArgs e)
{
Catalogos.frmSalarios salarios = new costeos.Catalogos.frmSalarios(ConnectionString);
salarios.ShowDialog(this);
salarios.Dispose();
}
private void agregarToolStripMenuItem_Click(object sender, EventArgs e)
{
Catalogos.frmAddRemuneraciones rem = new costeos.Catalogos.frmAddRemuneraciones(ConnectionString);
rem.ShowDialog(this);
rem.Dispose();
}
private void agregarToolStripMenuItem1_Click(object sender, EventArgs e)
{
Catalogos.frmAddAdmin adm = new costeos.Catalogos.frmAddAdmin(ConnectionString);
adm.ShowDialog(this);
adm.Dispose();
}
private void agregarToolStripMenuItem2_Click(object sender, EventArgs e)
{
Catalogos.frmAddInsumosInd insumos = new costeos.Catalogos.frmAddInsumosInd(ConnectionString);
insumos.ShowDialog(this);
insumos.Dispose();
}
private void txt_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsDigit(e.KeyChar) || char.IsPunctuation(e.KeyChar) || char.IsControl(e.KeyChar))
{
e.Handled = false;
}
else
{
e.Handled = true;
}
}
private void inicio_Load(object sender, EventArgs e)
{
LlenaCampos();
}
private void LlenaCampos()
{
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var mat = session.CreateCriteria(typeof(Material))
.List<Material>();
var sal = session.CreateCriteria(typeof(Salarios))
.List<Salarios>();
transaction.Commit();
cmbMaterial.DataSource = mat;
cmbMaterial.DisplayMember = "Nombre";
cmbSalarios.DataSource = sal;
cmbSalarios.DisplayMember = "Nombre";
cmbMIndirecta.DataSource = sal;
cmbMIndirecta.DisplayMember = "Nombre";
}
}
}
private void btnAddMaterial_Click(object sender, EventArgs e)
{
materialBindingSource.DataSource = null;
//dgvMaterial.DataSource = null;
mater.Add((Material)cmbMaterial.SelectedValue);
//dgvMaterial.DataSource = mater;
dgvMaterial.DataSource = materialBindingSource;
materialBindingSource.DataSource = mater;
materialBindingSource.ResetBindings(false);
}
private void button2_Click(object sender, EventArgs e)
{
dgvSalarios.DataSource = null;
salar.Add((Salarios)cmbSalarios.SelectedValue);
dgvSalarios.DataSource = salar;
}
private void button3_Click(object sender, EventArgs e)
{
dgvMIndirecta.DataSource = null;
mind.Add((Salarios)cmbMIndirecta.SelectedValue);
dgvMIndirecta.DataSource = mind;
}
private void button1_Click(object sender, EventArgs e)
{
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
if (prod == null)
{
prod = new Productos { CargasTurno = float.Parse(txtCargasTurno.Text), CavidadesMolde = int.Parse(txtCavidadesMolde.Text), Clave = txtClave.Text, Comentarios = txtComentarios.Text, MezclasTurno = float.Parse(txtMezclasTurno.Text), Moldes = int.Parse(txtMoldes.Text), Nombre = txtNombre.Text, Peso = float.Parse(txtPesoTotal.Text), TotalPza = int.Parse(txtPzasTotales.Text), Turnos = int.Parse(txtTurnos.Text) };
session.Save(prod);
transaction.Commit();
}
foreach (DataGridViewRow dr in dgvMaterial.Rows)
{
Material m = dr.DataBoundItem as Material;
m.Materiales
PMaterial mat = new PMaterial { Material = dr.DataBoundItem as Material, Cantidad = float.Parse(dr.Cells["Cantidad"].Value.ToString()), Fecha = DateTime.Now, Producto = prod };
session.Save(mat);
}
transaction.Commit();
session.Close();
}
}
}
}
}
That's probably not DGV problem, but with this combo box. Show us the code that fills combo box and sets its properties.
If you are casting to Material class you should probably use SelectedItem instead of SelectedValue. (unless you exactly know what you're doing)
I would guess that you have an event-handler that isn't happy. What exactly does the message say?
You might also be having problems if you are adding the same Material instance to the list multiple times; since IndexOf will only find the first occurrence. This line makes me very suspicious:
mater.Add((Material)cmbMaterial.SelectedValue);
since it could potentially (on consecutive clicks / etc) do exactly this.
Note: if you used BindingList<T> instead all you'd have to doo is Add(...) - no resetting required:
field:
BindingList<Material> mater = new BindingList<Material>();
init grid:
dgvMaterial.DataSource = mater;
add item:
mater.Add(newInstance);
If you assign data source to the DGV you should check element count - if zero then assign null. I don't know why this is the way it is, but I'm doing it in all my forms.
//I'm still analysing the rest of the code

Categories

Resources