#c# #linq-to-sql
#c# #linq-to-sql
Вопрос:
Приведенный ниже метод, который обновляет базу данных, называется UpdateHold(). Этот экземпляр объекта использует второй конструктор. Я запустил debug, чтобы убедиться, что объект хранения «thisHold» обновляет значения, которые изменяются в форме. Но когда я просматриваю значения объекта db после отправки, я вижу, что он не изменился, такой же в физической базе данных. Почему это не обновляется?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Data.Linq;
using System.Text;
using System.Windows.Forms;
namespace Coke_Hold_Database
{
public partial class frmFGHold : Form
{
private PINAuthentication cert = new PINAuthentication();
linqCokeDBDataContext db = new linqCokeDBDataContext();
Record_HoldData thisHold;
bool isNew; //flag if hold is new or not
public frmFGHold()
{
//constructor for new hold
InitializeComponent();
populateLists();
thisHold = new Record_HoldData();
isNew = true;
btnEdit.Visible = false;
}
public frmFGHold(Record_HoldData holdData)
{
//constructor for existing hold (edit)
InitializeComponent();
populateLists();
this.thisHold = holdData;
//fill out the form
FillForm();
isNew = false;
btnEdit.Visible = true;
}
private void FillForm()
{
//fill out the form with existing information
txtPONumber.Text = thisHold.PO_.ToString();
cboProductionSupervisor.SelectedValue = thisHold.ProductionSupervisor;
cboLineNumber.SelectedValue = thisHold.LineNumber;
cboQASupervisor.SelectedValue = thisHold.QASupervisor;
cboFlavorName.SelectedValue = thisHold.Flavor;
cboContainer.Text = thisHold.ContainerType;
cboContainerSize.Text = thisHold.ProductSize;
cboPackage.Text = thisHold.Package;
txtQuantity.Text = thisHold.HoldQty.ToString();
mtbDateCode.Text = thisHold.DateCode;
cboDefectiveComponent.Text = thisHold.NonConformingItem;
cboDefectReason.Text = thisHold.NonConformance;
cboOccuredAt.Text = thisHold.FoundDuring;
chkTestRequired.Checked = (bool) thisHold.TestRequired;
txaDescription.Text = thisHold.Comments;
txaRootCauseAnalysis.Text = thisHold.RootCause;
}
private void UpdateHoldObject()
{
thisHold.PO_ = int.Parse(txtPONumber.Text);
thisHold.ProductionSupervisor = (int)cboProductionSupervisor.SelectedValue;
thisHold.LineNumber = (int) cboLineNumber.SelectedValue;
thisHold.QASupervisor = (int) cboQASupervisor.SelectedValue;
thisHold.Flavor = (int) cboFlavorName.SelectedValue;
thisHold.ContainerType = cboContainer.Text;
thisHold.ProductSize = cboContainerSize.Text;
thisHold.Package = cboPackage.Text;
thisHold.HoldQty = int.Parse(txtQuantity.Text);
thisHold.DateCode = mtbDateCode.Text;
thisHold.NonConformingItem = cboDefectiveComponent.Text;
thisHold.NonConformance = cboDefectReason.Text;
thisHold.FoundDuring = cboOccuredAt.Text;
thisHold.TestRequired = chkTestRequired.Checked;
thisHold.Comments = txaDescription.Text;
thisHold.RootCause = txaRootCauseAnalysis.Text;
}
private void CreateNewHold()
{
db.Record_HoldDatas.InsertOnSubmit(thisHold);
//GenerateHoldNumber()
db.SubmitChanges();
MessageBox.Show(this, "Hold submitted!nnYou're hold number is " thisHold.HoldID.ToString(),"Hold #" thisHold.HoldID.ToString() " created", MessageBoxButtons.OK, MessageBoxIcon.Information);
this.Close();
}
private void UpdateHold()
{
db.SubmitChanges();
MessageBox.Show(this, "Hold #" thisHold.HoldID.ToString() " updated.", thisHold.HoldID.ToString() " updated", MessageBoxButtons.OK, MessageBoxIcon.Information);
this.Close();
}
private bool ValidateEntry()
{
//TODO write some frakkin validation
return true;
}
private void GetPIN()
{
frmPINPrompt pin = new frmPINPrompt(cert);
pin.ShowDialog();
}
private void SubmitData()
{
UpdateHoldObject();
GetPIN();
if (ValidateEntry() amp;amp; cert.authenticated)
{
try
{
if (isNew)
{
thisHold.LabTech = cert.empNumber;
thisHold.LastEditBy = cert.empNumber;
thisHold.HoldStatus = "Open";
thisHold.DateOpened = DateTime.Now;
thisHold.LastEditDate = DateTime.Now;
CreateNewHold();
}
else
{
thisHold.LastEditBy = cert.empNumber;
thisHold.LastEditDate = DateTime.Now;
UpdateHold();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
public void populateLists()
{
//load production names
var productionNames =
from a in db.LUT_Employees
where a.position == "Supervisor" amp;amp; a.department == "Production"
select new { ID = a.ID, Names = a.lastName ", " a.firstName };
cboProductionSupervisor.DataSource = productionNames;
cboProductionSupervisor.DisplayMember = "Names";
cboProductionSupervisor.ValueMember = "ID";
//load QA names
var qaNames =
from a in db.LUT_Employees
where a.position == "Supervisor" amp;amp; a.department == "Quality Assurance"
select new { ID = a.ID, Names = a.lastName ", " a.firstName };
cboQASupervisor.DataSource = qaNames;
cboQASupervisor.DisplayMember = "Names";
cboQASupervisor.ValueMember = "ID";
//load flavor names
var flavorNames =
from a in db.LUT_Flavors
select new { ID = a.ID, Flavor = a.flavor };
cboFlavorName.DataSource = flavorNames;
cboFlavorName.DisplayMember = "flavor";
cboFlavorName.ValueMember = "ID";
//load line numbers
var lineNumbers =
(from a in db.LUT_ProductionLines
select new { a.lineNumber }).ToList();
cboLineNumber.DataSource = lineNumbers;
cboLineNumber.DisplayMember = "LineNumber";
cboLineNumber.ValueMember = "LineNumber";
}
private void mtbDateCode_MouseUp(object sender, MouseEventArgs e)
{
SendKeys.Send("{HOME}");
}
private void btnCancel_Click(object sender, EventArgs e)
{
DialogResult result = MessageBox.Show("Are you sure you want to cancel? All data will be lost!", "Confirm Cancel", MessageBoxButtons.YesNo, MessageBoxIcon.Asterisk);
if (result == DialogResult.Yes)
{
this.Close();
}
else { }
}
private void btnSubmit_Click(object sender, EventArgs e)
{
SubmitData();
}
private void linkAutoFill_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
//autogenerage date code
mtbDateCode.Text = Etc.BuildDateCode(DateTime.Now,(int)cboFlavorName.SelectedValue,cboContainer.Text,Etc.getDayCode(DateTime.Now),int.Parse(cboLineNumber.Text));
}
private void cboContainerSize_SelectedIndexChanged(object sender, EventArgs e)
{
//load package sizes
var packageSizes =
from a in db.LUT_Packagings
where a.Container == cboContainer.Text amp;amp; a.Size == cboContainerSize.SelectedValue
select new { ID = a.ID, Size = a.Package };
cboPackage.DataSource = packageSizes;
cboPackage.DisplayMember = "Size";
cboPackage.ValueMember = "ID";
}
private void cboContainer_SelectedIndexChanged(object sender, EventArgs e)
{
//make container size list
var containerSizes =
from a in db.LUT_Containers
where a.ContainerType == cboContainer.Text
select new { ID = a.ID, Size = a.size };
cboContainerSize.DataSource = containerSizes;
cboContainerSize.DisplayMember = "Size";
cboContainerSize.ValueMember = "ID";
//load components
var defectiveComponents =
from a in db.LUT_ContainerComponents
where a.Container == cboContainer.Text
select new { ID = a.ID, Comp = a.Component };
cboDefectiveComponent.DataSource = defectiveComponents;
cboDefectiveComponent.DisplayMember = "Comp";
cboDefectiveComponent.ValueMember = "ID";
}
private void btnEdit_Click(object sender, EventArgs e)
{
//TODO ask verify PIN
foreach (Control c in this.Controls)
{
c.Enabled = true;
}
btnSubmit.Text = "Update Hold";
}
}
}
Комментарии:
1. Вы пытаетесь обновить одну строку или несколько обновлений??
2. одна строка. обычно у меня не возникает проблем с submitall
Ответ №1:
База данных не обновляется, потому что вы отправляете изменения в db
DataContext, а ‘hold’, который вы предоставили через конструктор, не привязан к этому DataContext. Следовательно, db
DataContext не может отслеживать изменения, которые вы внесли в объект.
Вы могли бы попробовать использовать DataContext.Attach
или, что еще лучше, предоставить форме исходный контекст данных, из которого был загружен объект.
Комментарии:
1. каково ваше мнение по поводу инициализации контекста данных в глобальной области видимости класса вместо использования
using
блока внутри каждого метода, который должен использовать контекст данных?2. @Nick, ПЛОХАЯ идея, и все равно это не решит вашу проблему, поскольку таким образом каждый класс получает свой собственный контекст данных. Ваша формулировка
using
также пугает меня, потому что это создает еще больше контекстов данных. Лучшим решением было бы определить «единицы работы» (т. Е. обновить объект) и создать один контекст данных для этой единицы работы и передать указанный контекст данных классам и методам, которым это необходимо. Возможно, вы захотите изучить внедрение зависимостей.3. Я имел в виду единицы работы, подобные тем, которые вы описали. Полезно получить второе мнение. Спасибо за ваш совет.
4. бинго. я знал, что это как-то связано с datacontext. учитывая, что у меня в голове не укладывалось, как он будет знать, что использовать. все еще немного новичок в этом, пытаюсь разобраться. Спасибо!