I am really confused about why an update is not taking place. This is very simple:
int goodID = 100;
DataContext db = new DataContext();
Schedule schedule = db.Schedules.Single(s => s.ID == goodID);
// this wont persist - WHY NOT?!
schedule.Email = txtEmail.Text;
// this does persist
schedule.NumberCourses = 5;
db.SubmitChanges();
I can't understand why the field, Email, isn't getting the value from the textbox. What can I check?
EDIT
I have set a breakpoint and checked the value after assignment. It assigns the textbox value but still no update.
Check what changes will be submitted to the datacontext.
Add a breakpoint just before the db.SubmitChanges() line gets executed and add the following Watch:
db.GetChangeSet();
In the Watch (or Quick Watch) window you'll be able to see which changes are being submitted.
Set a breakpoint and check the value of schedule.Email before and after that line. Also, use the immediate window to check txtEmail.Txt to see if it actually contains data.
Tell us what you find.
Does that dbml match the database table? If it doesn't match the database, you can get weird things. Try reimporting it.
I am an idiot. It's fixed. Votes for everyone.
Instead of checking in the database, like a normal person would, I was just looking on the webform after refreshing the page. I wasn't initializing the textbox with the value from the db. So the update was happening. See? I told you I was an idiot.
Related
I have a function that saves an XML file and then binds it to a gridview. My problem is that the gridview is updating before the file is done saving.
So far I've been able to get the save to occur first by inserting a 1 second pause, however, I realize that this is a terrible, not to mention unreliable, way of getting the desired result. My code currently looks like this
editingFunction();
gsXML.Save(Server.MapPath("~/xmlFile.xml"));
System.Threading.Thread.Sleep(1000); // Ill-advised, I know...
XmlDataSource1.Data = gsXML.OuterXml;
XmlDataSource1.DataBind();
updatePanel1.Update();
Does anyone know a better way to ensure that the save function occurs before the binding?
EDIT: It seems that I misdiagnosed the problem. The save function was in fact executing first, however, I needed to clear the XmlDataSource.Data first by calling 'XmlDataSource1.Data = null.' Thanks to Graffito for pointing this out!
As the DataGridView is already bound to its source, the instruction " XmlDataSource1.Data = gsXML.OuterXml" does not operate.
To force a new binding, remove the binding first:
XmlDataSource1.Data = null.
XmlDataSource1.Data = gsXML.OuterXml
I have a WinForm that have a DataGridView and a ComboBox, allowing users to select a subject (from the database).
cbxSubject.DataSource = dsSched.Tables["Schedules"];
cbxSubject.DisplayMember = "Subject";
...
The DataGridView looks something like this: http://i45.tinypic.com/18gmmu.png I added the DataGridView since I don't know any other way how to get those values from the database. I used a code, something like this, to get the values:
TextBox1.Text = DataGridView1.Rows[3].Cells[1].Value.ToString();
But then I realized that it won't work anymore if there are more than 2 subjects to choose from, because the code is set to get the value on the 3rd row and the 1st cell. So even when the user changed subject, the output value (w/c are then displayed in a TextBox) will still be the same. Are there any other ways to get those values? Please help, thanks.
You can add a comboxbox this way
DataGridViewComboBoxColumn subjectsCombo = new DataGridViewComboBoxColumn();
subjectsCombo.DataPropertyName = "SubjectID";
subjectsCombo.HeaderText = "Subjects";
subjectsCombo.DataSource = dsSched.Tables["Subjects"];
subjectsCombo.ValueMember = "SubjectID";
subjectsCombo.DisplayMember = "SubjectText";
cbxSubject.Columns.Add(subjectsCombo);
I would suggest that you DONT use constants. Rather that using 3 and 1, you need to write some code to find R and C from what the user selects. It should be event driven and you need to re-set the text box on change. I'm assuming you are using an on-change event, but you haven't actually given us that information yet.
here's some pseudocode to get where im going with this
public DataGridView1_SelectionChanged(object sender, ChangedEventArgs e)
{//this might not be the right event, I'll leave it up to you to do your own homework
int R = //Get the current Selected Row;
int C = //Get the current Selected Cell/column;
TextBox1.Text = dsSched.Tables["Schedules"].Rows[R].Cells[C];
///OR YOU COULD DO SOMETHING LIKE THIS
TextBox1.Text = ((DataGridView)sender).SelectedRows[0].Cells[1].Value;
}
//Please note, this is only pseudocode, I dont like doing peoples homework for them.
This should give you a more generic idea/algorithm that you would need. Keeping in mind that this might not even be the best way to go about doing this, but Its what I would recommend based solely on the information provided to us thus far. btw, what have you tried? and can you give us some larger code examples, there might be a rather more simple mistake being made that you haven't shown us so we cant tell you about it :-)
Considering that you still haven't actually asked the correct question, because we dont know WHY you are trying to do what you have stated you are doing, I can't get any more specific than this. GIGO, you have to ask the right question in order to get the right answer.
I'll try to get some of your doubts out of the way:
I added the DataGridView since I don't know any other way how to get
those values from the database
You already have a DataSet called "dsSched" filled with database values. So, no, you don't need the DataGridView. Just fill whatever you want directly from the DataSet:
string data = dsSched.Tables["Schedules"].Rows[3].Cells[1].Value.ToString();
then I realized that it won't work anymore if there are more than
2 subjects to choose from, because the code is set to get the value on
the 3rd row and the 1st cell.
Well, I'm not sure where you are running that piece of code (TextBox1.Text = Data...), but if you are running it on the SelectedIndexChanged event of the DataGridView, then you should get data from the exact row that the user selected (or something, again, I did not understood what you are trying to do).
One thing that I suspect is that you are under the impression that the code:
TextBox1.Text = DataGridView1.Rows[3].Cells[1].Value.ToString();
...is binding the textbox to the value in the row / cell. That's not how this works - the value is retrieved once when the code is run, and then again whenever the code is run again. So you should make sure the code is run when you have to get this value.
EDIT:
I mean, how do I get the value? Like, the PrimaryKey or something?
That's the question! I'm sorry, I was probably deviating. Just set the [ValueMember][1] to the string that describes the value column of the dataset.
cbxSubject.ValueMember = "Schedule ID";
Than you access it using [SelectedValue][2], like:
int selValue = (int)(cbxSubject.SelectedValue);
I have a list view with two colums in wpf Customername and Isvalid.I am using linq to sql to get the data from my sql table.when i am trying to update a value to the table i dont see any changes to the table.
Here is my code when i click on the save button:
try
{
CustomersDataContext dataContext = new CustomersDataContext();
Customer customerRow = MyDataGrid.SelectedItem as Customer;
string m = customerRow.CustomerName;
Customer customer = (from p in dataContext.Customers
where p.CustomerName == customerRow.CustomerName
select p).Single();
customer.Isvalid=false;
dataContext.SubmitChanges();
MessageBox.Show("Row Updated Successfully.");
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
return;
}
I can see that i am able to query the record based on the customername selected but the value is not updating.
I would be glad if some one can point out where am i missing the logic to update the "ISVALID" value to the data base.
Firstly, where's your using(get_datacontext){...} block? You need to dispose of DataContexts when you are done with them!
Anyway...
My guess is that the update statement is generating a where clause that's far too tight, or just plain wrong.
I would be checking the 'Update Check' property of each of the columns in your mapped table in the Linq to Sql designer. The simplest thing to do is to set the primary key column to Always and set all the others to Never. You can also consider setting them to WhenChanged.
The designer's default behaviour is generally to set it to Always for everything; not only does this cause horrible WHERE clauses for updates, but can occasionally also cause problems. Obviously such behaviour is required for proper concurrency checking (i.e. two threads updating the same row); so be aware of that.
Oh, thinking of something else - you can also get this behaviour if your table doesn't have a primary key designated in the designer - make sure one of the columns is.
Finally you can check the SQL being generated when SubmitChanges is called; by attaching a TextWriter to the DataContext.Log property; or equally IntelliTrace in VS2010 will collect all ADO.Net queries that are run if you start with debugging. This is invaluable in debugging why L2S stuff isn't working as expected.
You should Add updated Customer to list of updating customers. I mean before saving changes you should do something like: db.AddToCustomers(customer). AddToCustomers in used in EF, I exactly don't know its equivalent in LINQ.
Hey guys, I'm having a weird time with Linq-To-SQL
I'm building a postit system that allows people to make postits and attach them to multiple objects. The database for this is a table that has the postits themselves (id, message, etc) and a linkstable which holds the records to which a postit is attached.
the weird thing I'm experiancing is the following.
When I retrieve an object from the database (using Linq-To-SQL), do some data changing and submit it again, I experience no trouble whatsoever.
Yet, when I try to make a new one I get an exception in the Submitchanges method in the datacontext: Specified Cast is not valid.
I've been looking on the web and mostly it involves some change in the mapping, but this shouldn't be the case as I can update without any problems.
T_PostIt np = new T_PostIt();
np.CreatedOn = DateTime.Now;
np.CreatedBy = Request.ServerVariables["REMOTE_USER"].ToString();
np.MarkedForDeletion = false;
np.Message = txtNewPostitMessage.Text;
np.ModifiedBy = Request.ServerVariables["REMOTE_USER"].ToString();
foreach (int i in ServerIds)
{
T_PostIt_Link pil = new T_PostIt_Link();
pil.LinkType = 'S';
pil.LinkID = i;
pil.MarkedForDeletion = false;
np.T_PostIt_Links.Add(pil);
}
dc.T_PostIts.InsertOnSubmit(np);
dc.SubmitChanges();
I use the above code and can't seem to get what I'm doing wrong.
help anyone?
Have you tried updating the properties one by one, and then save the changes back to the database? It could be that updating the entity only fails when one specific value has changed. If I may guess, it could be that the value of CreatedOn cannot be cast to a valid DateTime in the database (due to culture settings). That would explain why updating goes OK - you're not changing the value of CreatedOn here. You do, however, when inserting a new entity.
Edit: maybe this is the problem you're facing. Also, be sure to read this thread, where the topic starter eventually points to the first thread mentioning that it is an apparant bug in Linq2Sql.
I posted this question yesterday evening, which has led me to discover a huge problem!
I have a decimal column in my database called Units, anytime I set the value of the column to a NON ZERO, and SubmitChanges the column updates with the new value. If I try to set the value of the column to ZERO, the SubmitChanges does not update the column.
data.Units = this.ReadProperty<decimal>(UnitsProperty);
data.UnitPrice = this.ReadProperty<decimal>(UnitPriceProperty);
data.Price = this.ReadProperty<decimal>(PriceProperty);
I've taken a look at the DataContext log and I can see that the field with the ZERO value is not included in the query. Even if I try to hard code the change Linq ignores it.
data.Units = 0;
data.UnitPrice = 0;
data.Price = 0;
Needless to say this is killing me! Any ideas why this happening?
Solution
I figured out my problem with the help of the SO community. My problem was being caused by the fact when I created my entity to attach, the default value of the column was set to zero, so when it tried to assign the value to zero ... LinqToSql says hey ... nothing changed, so I am not updating the value.
What I am doing now ... just to make it work is the following:
ctx.DataContext.InvoiceItems.Attach(data, true);
That seems to force all the values to write themselves to the database. This works for now.
I have tried to reproduce this with a the following code, but for me it works.
using (DataClasses1DataContext ctx = new DataClasses1DataContext())
{
var obj = ctx.DecimalColumnTables.First();
Debug.Assert(obj.B != 0);
obj.B = 0;
ctx.SubmitChanges();
}
So I think there must be something special in your domain that causes this. I suggest you to create a such simple repro with your domain model and see what happens.
LINQ to SQL ignores updates to the current value, so if the field was already zero, you may not see any updates.
Off: The OR/M you use is LINQ to SQL. LINQ is the name of the querying capability in .NET, but LINQ does not define nor implement any update logic. So the issue relates to LINQ to SQL, not LINQ.
Obvious question, but are you sure the column is mapped in the dbml / mapping file?
Also - is it a calculated column? (i.e. price => units * unitprice)
I figured out my problem with the help of the SO community. My problem was being caused by the fact when I created my entity to attach, the default value of the column was set to zero, so when it tried to assign the value to zero ... LinqToSql says hey ... nothing changed, so I am not updating the value.
What I am doing now ... just to make it work is the following:
ctx.DataContext.InvoiceItems.Attach(data, true);
That seems to force all the values to write themselves to the database. This works for now.
Some more information ... I figured out my problem ... it's more of a lack of understanding about LinqToSql ... where I am doing:
private void Child_Update(Invoice parent)
{
using (var ctx = Csla.Data.ContextManager
.GetManager(Database.ApplicationConnection, false))
{
var data = new Gimli.Data.InvoiceItem()
{
InvoiceItemId = ReadProperty(InvoiceItemIdProperty)
};
ctx.DataContext.InvoiceItems.Attach(data);
if (this.IsSelfDirty)
{
// Update properties
}
}
}
I thought this would load the original values ... what happens is that it creates a new object with default values ... empty values, like 0 for decimals, Guid.Empty for uniqueidentifiers and so on.
So when it updates the properties it sees the Units already as 0 and it sets it to zero. Well LinqToSql doesn't recognize this as a change so it doesn't up date the field. So what I have had to do is the following:
ctx.DataContext.InvoiceItems.Attach(data, true);
Now all the modifications are generated in the update statement whether there is really a change or not. This works ... seems a bit hackish!
The correct answer is as many pointed out to use the special overload of Attach which accepts a boolean parameter to consider it as modified, (make the mistake of using another overload and it simply won't work):
ctx.DataContext.InvoiceItems.Attach(data, true);
Note however that you still might need to have a "Version" column in the table of type "timestamp".
I had this problem and all the suggestions I'd seen didn't apply or work.
But I found I had made a very simple mistake!
When updating the property I was actually calling a custom Set method (because there were other things that needed to be changed in response to the main property in question).
After hours of head scratching I noticed that my Set method was updating the private member not the public property, i.e. this._Walking = value;
All I had to do was change this to this.Walking = value; and it all started to work!