I am experimenting with Azure and am running into an issue I cannot seem to find an answer to.
I am running a linq query to update Azure Database with changes to a record but for some reason the changes are not being noted or submitted to the database. The code I am running is as follows:
DataClasses1DataContext update = new DataClasses1DataContext();
Company extra = update.Companies.Single(p => p.ID == Convert.ToInt32(Request.QueryString["ID"]));
extra.companyName = txtCompanyName.Text;
extra.address1 = txtAddress1.Text;
extra.address2 = txtAddress2.Text;
extra.address3 = txtAddress3.Text;
extra.address4 = txtAddress4.Text;
extra.town = txtTown.Text;
extra.county = txtCounty.Text;
extra.postCode = txtPostCode.Text;
extra.billingEmail = txtBillingEmail.Text;
extra.facebook = txtFacebook.Text;
extra.fax = txtFaxNumber.Text;
extra.faxArea = txtFaxArea.Text;
extra.faxCountry = txtFaxCountry.Text;
extra.linkedIn = txtLinkedIn.Text;
extra.mainEmail = txtMainEmail.Text;
extra.mainPhone = txtMainLineNumber.Text;
extra.mainPhoneArea = txtMainLineArea.Text;
extra.mainPhoneCountry = txtMainLineCountry.Text;
if (drpMarketing.Text == "No")
{
extra.marketingYesNo = 0;
}
else
{
extra.marketingYesNo = 1;
}
extra.salesEmail = txtSalesEmail.Text;
extra.twitter = txtTwitter.Text;
extra.website = txtWebsite.Text;
update.SubmitChanges();
What I am noticing by setting break points is that if I load the page and then change some data then the new data is not being reflected when this code is called (it is in a btnUpdate_Click event)
So When the submitChanges() is used then the new data is not present to submit. Any help appreciated.... I think I have looked at this for so long it needs some fresh eyes lol.
Are you sure you are not repopulating your form OnPostback with the original data (re-selected from the database) so that the linq update actually works, but you are always submitting the most recent database data back to the database.
In other words are you sure you are only populating your form
if(!Page.IsPostback)
{
//populate the form
}
this will preserve user amends when a postback happens.
Have you tried to wrap the SubmitChanges in a try block? Maybe it is throwing an exception. Here is how it is documented to do updates which is very similar to what you are doing:
http://msdn.microsoft.com/en-us/library/bb399339.aspx
Also, does this work against a local SQL Server database or SQL Express database?
Related
I have a small C# console application who's sole purpose is to receive records from a "Saved Search" in NetSuite(via SuiteTalk). I've been able to successfully connect and receive records from NetSuite for my Saved Search(the search runs fine through the web interface too), however when I attempt to access the results of the "Saved Search" through my application, I am unable to view them because the search object that is returned does not contain any data in the "recordList" property:
//Connect
var dataCenterAwareNetSuiteService = new DataCenterAwareNetSuiteService("XXXXXX");
dataCenterAwareNetSuiteService.Timeout = 1000 * 60 * 60 * 2;
//Adds Credentials etc...
dataCenterAwareNetSuiteService.tokenPassport = createTokenPassport();
//Setup Preferences
var prefs = new Preferences();
prefs.warningAsErrorSpecified = true;
prefs.warningAsError = false;
dataCenterAwareNetSuiteService.preferences = prefs;
var searchPrefs = new SearchPreferences();
dataCenterAwareNetSuiteService.searchPreferences = searchPrefs;
dataCenterAwareNetSuiteService.searchPreferences.pageSize = 5;
dataCenterAwareNetSuiteService.searchPreferences.pageSizeSpecified = true;
dataCenterAwareNetSuiteService.searchPreferences.bodyFieldsOnly = false;
dataCenterAwareNetSuiteService.searchPreferences.returnSearchColumns = false;
//Search
var tranSearchAdv = new TransactionSearchAdvanced();
var tranSearchRow = new TransactionSearchRow();
var tranSearchRowBasic = new TransactionSearchRowBasic();
tranSearchAdv.savedSearchId = "XXXX";
tranSearchRowBasic.internalId =
new SearchColumnSelectField[] { new SearchColumnSelectField() };
tranSearchRowBasic.tranId =
new SearchColumnStringField[] { new SearchColumnStringField() };
tranSearchRowBasic.dateCreated =
new SearchColumnDateField[] { new SearchColumnDateField() };
tranSearchRowBasic.total =
new SearchColumnDoubleField[] { new SearchColumnDoubleField() };
tranSearchRowBasic.entity =
new SearchColumnSelectField[] { new SearchColumnSelectField() };
tranSearchRow.basic = tranSearchRowBasic;
tranSearchAdv.columns = tranSearchRow;
//No errors,
//this works correctly and returns the "Saved Search" with the correct "totalRecords"
//but results.recordList == null while results.totalRecords = 10000000+
var results = dataCenterAwareNetSuiteService.search(tranSearchAdv);
I appears to me that the "recordList" object is the principal way data is retrieved from the results of a search(Related Java Example, Another Here). This is also the way the example API does it.
I have run this on multiple "Saved Search's" with the same results. I don't understand how you can have more than one record in "totalRecords" and yet the "recordList" remains null? Is there some configuration option that has to be set to allow me to access this property. Or maybe it's a security thing, the API user I have setup should have full access, is there anything else that need to be granted access?
NetSuite SuiteTalk is not well documented, and most of the examples online are not in C#, and not dealing with the issues that I'm experiencing. These factors make it very difficult to determine why the previously mentioned behavior is occurring, or even, to discover any alternative methods for retrieving the resulting data from the source "Saved Search".
Does anyone have any insight into this behavior? Is this the correct method of retrieving results from SuiteTalk? Is there any configuration from the API or Web Side that needs to be changed?
Update 1
I've also tried using the alternative way of getting result data by accessing the "searchRowList" object from the "SearchResult" object(suggested by #AdolfoGarza) However it returns mostly empty fields(null) similar to the "recordList" property I do not see a way to retrieve "Saved Search" data from this method.
Try getting the results with results.searchRowList.searchRow , thats how it works in php.
I was able to resolve the issue by removing this line in the code:
tranSearchRow.basic = tranSearchRowBasic;
Then like #AdolfoGarza reccomended, retrieving the results from "basic" field in "results.searchRowList"
For some reason the template API that I was using was setting up a "TransactionSearchAdvanced" referencing a blank "TransactionSearchBasic" record, not sure why but this was causing the results from "searchRowList" to be null. After removing it I now get non-null values in the proper fields.
As for "recordList", it's still null, not sure why, but as I have my data I don't think I'll continue to dig into this.
I have a C# windows application in which there are many crystal reports.I call and show them using the following piece of code :
rptDDCollection rpt = new rptDDCollection();
rpt.SetDatabaseLogon(Connect.sDatabaseUserName, DLL.Connect.sDatabasePassword, "", Connect.sCurrentDatabase);
rpt.RecordSelectionFormula = "";
frmReports frm = new frmReports();
frm.crViewer1.DisplayGroupTree = false;
frm.crViewer1.ReportSource = rpt;
frm.crViewer1.SelectionFormula = rpt.RecordSelectionFormula;
frm.crViewer1.Show();
frm.Show();
Now, the issue is that I have 2 databases to work on.Things work fine with one database.I have to use the same report but very often I need to view data from the other database.The database engine is SQL server.While searching on the net and on stack overflow, I found suggestions to set the database name dynamically through code.What should be done to achieve what I want in this case?
I worked this around by setting database name for the tables in the report.I made one change in the actual code above.I created a method called ApplyLogonInfo and passed the report object to it.Inside the method I wrote the code for setting database name for the report tables dynamically.This is the modified code:
rptDDCollection rpt = new rptDDCollection();
rpt.SetDatabaseLogon(Connect.sDatabaseUserName, DLL.Connect.sDatabasePassword, "", Connect.sCurrentDatabase);
ApplyLogOnInfo(rpt);
rpt.RecordSelectionFormula = "";
frmReports frm = new frmReports();
frm.crViewer1.DisplayGroupTree = false;
frm.crViewer1.ReportSource = rpt;
frm.crViewer1.SelectionFormula = rpt.RecordSelectionFormula;
frm.crViewer1.Show();
frm.Show();
Below is the newly created method:
public static void ApplyLogOnInfo(ReportClass rpt)
{
TableLogOnInfo info = new TableLogOnInfo();
info.ConnectionInfo.DatabaseName = Connect.sCurrentDatabase;
for (int i = 0; i < rpt.Database.Tables.Count; i++)
{
rpt.Database.Tables[i].ApplyLogOnInfo(info);
}
}
sCurrentDatabase is the name of the database that has been currently selected for viewing.
This enabled me to set the database name dynamically, and now I can work with 2 (or in general multiple) databases and view the data from whichever database I wish to see.
I am using EF with Oracle..
I have a test that will run this bit of code
using (var ctx = new Entities())
{
ctx.SOMEOBJECTSESSIONs.Add(
new SOMEOBJECTSESSION()
{
SOMEOBJECTSESSIONID = 0,
SOMEOBJECTSESSIONIDHASH = hash,
DEVICEDESC = "some device",
OPERATINGSYSTEMDESC = "Microsoft Windows NT 6.1.7601 Service Pack 1",
BROWSERDESC = "Chrome27",
IPADDRESS = "123.132.123.132",
SOMEOBJECTSESSIONSTATUSID = 9999999999,
CREATEDBYSOMEOBJECTID = 9999999999,
CREATEDDATE = DateTime.Now,
UPDATEDBYSOMEOBJECTID = 9999999999,
UPDATEDDATE = DateTime.Now
}
);
ctx.SaveChanges()
}
Using this I add a record to the database.. I then went into the database and manually deleted that record..
When I try and run this test again, the call to SaveChanges dies, just sits there.. Now If I do a
var tmp = ctx.SOMEOBJECTSESSIONs.Count();
I get back a count that is one more than what is in the database.. Which to me suggests EF still has a hook locally to the record I deleted..
I have read numerous articles about refreshing context(didn't work). I have cleared the "Local"
ctx.SOMEOBJECTSESSIONs.Local.Clear()
which also did not work..
I would have thought that the fact I am spawning up a new Entities connection it should be getting the data from the database..
How do I fix this? What am I doing wrong?
Cheers,
J
Create your context as late as possible and dispose it as soon as you are ready.
So preferably dispose it and create a new one; or use Reload, as described in Entity Framework Refresh context?.
I am using linq to sql in a windows form application. there is a bug that I couldn't find the solution until now!
partial void OnAmountChanging(int? value)
{
OrderLog lg = new OrderLog()
{
Date = DateTime.Now,
IPAddress = System.Net.Dns.GetHostAddresses(Environment.MachineName)[0].ToString(),
NewData = value,
OldData = this.Amount,
Status = "Changed",
User = User.CurUser,
Order = this // each Order has one-to-many relation to OrderLog entity.
};
}
this is run as soon as the value of AMOUNT changes in datagridview.
after closing the form I try to save the created log to Database:
db.SubmitChanges();
then I face this error :
An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported
is there any solution?
So, here is my hopefully unique spin on this common problem.
I do my query, get my objects then pass the object into a form where it populates the form with the data from the object (this is not passed in by reference).
I then edit the values of the object that was queried (via the form) and then return a new object constructed from the values in the form.
I then want to update this to the database. Attach does nothing (runs but does not update). SubmitChanges also does nothing (and both do nothing when used together).
What am I missing?
Update: here is the code I am using:
// In constructor
_dataMap = new DataMapDataContext();
_addresses = _dataMap.AddressItems
.Where(address => address.InsertUserName == _currentUser.Name).ToList();
public void EditButtonClick()
{
using (AddAddressForm form = new AddAddressForm(_addresses[_currentAddress]))
{
form.Text = "Edit Address";
if (DialogResult.OK == form.ShowDialog())
{
_addresses[_currentAddress] = form.Item;
_dataMap.SubmitChanges();
DisplayItem();
}
}
}
You'll need to get the record from the database, update it's values and then call SubmitChanges()
using(MyDataContext db = new MyDataContext())
{
// get the record
Product dbProduct = db.Products.Single(p => p.ID == 1);
// set new values
dbProduct.Quantity = 5;
dbProduct.IsAvailable = false;
// save them back to the database
db.SubmitChanges();
}
Turns out I was doing almost everything right.
I just needed to pass in the object I was editing by reference. That way when it got changed, it was not a new object that was returned, but the same one (that Linq-to-SQL already knew about.)
These are the two lines from the code above that got changed:
AddressItem itemToEdit = _addresses[_currentAddress];
using (AddAddressForm form = new AddAddressForm(ref itemToEdit))