Add an entity as LOG during property changing events of another entity - c#

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?

Related

Entity framework Context.SaveChanges not working at all

I'm having problems with this code. I´m able to connect to an mdf example database archive and generate the entity model. Althought I´m able to query the context model and retrieve information from the DB, when I try to update, delete or insert anything in the context and translate the changes to the DB Context.SaveChanges is not working. There is no Exception, the Entity model is updated properly, but the DB does not have the change.
Thanks in regard
public void addCourse(int courseId, int deptId, string courseTitle)
{
SchoolContexto = new SchoolEntities();
Course mycourse= new Course();
mycourse.CourseID = courseId;
mycourse.Credits = 10;
mycourse.DepartmentID = deptId;
mycourse.Title = courseTitle;
SchoolContexto.Courses.Add(mycourse);
SchoolContexto.SaveChanges();
SchoolContexto.Dispose();
}
Make property of .mdf file in your solution as
Copy to output Directory: "Copy only if newer"
Otherwise your db file will overwrite every time it runs
i suggest you to use this code :
public void addCourse(int courseId, int deptId, string courseTitle)
{
SchoolEntities entities = new SchoolEntities();
Course mycourse= new Course();
mycourse.CourseID = courseId;
mycourse.Credits = 10;
mycourse.DepartmentID = deptId;
mycourse.Title = courseTitle;
entities.Courses.Add(mycourse);
entities.SaveChanges();
}
if this is not working i suggest you to check your app.config file :)
Another way to add a new entity to the context is to change its state to Added. Have you tried this
using (var entities = new SchoolEntities())
{
Course mycourse= new Course();
mycourse.CourseID = courseId;
mycourse.Credits = 10;
mycourse.DepartmentID = deptId;
mycourse.Title = courseTitle;
context.Entry(mycourse).State = EntityState.Added;
entities.SaveChanges();
}
I think the Problem is that you working on localdb (.mdf) file .
I had the same problem but when i created new (sql server database connection)
Server name : (localdb)\MSSqlLocaldb .... it worked
A little off the subject but just in case you're here because you're performing an update and not an add, Check if you need a key on the table. I had a similar issue with EF Core. During an update on a table no error was generated but the SaveChanges returned 0. It wasn't until I tested adding a record, that it generated the key error. I resolved the key issue and the update went fine.
It happens because probably you don't have primary key in your Course entity.
I solved the problem by including the following namespace
using System.Data.SqlClient;

Run Update Statement in Xamarin Studio

I am using C# with xamarin studio. I can't find a working example to do an update statement against my db. I am trying to update a value of a record from 50 to 100.
This class represents one record in db:
[Table("record")]
public class Record
{
[PrimaryKey, AutoIncrementAttribute, Column("id")]
public int ID {get; set;}
[Column("value")]
public string Value {get; set;}
}
I can retrieve my records fine using:
string pathToDatabase = "mydb.db";
var db = new SqliteConnection (pathToDatabase);
myRecords = db.Query<Record>("SELECT * FROM records;");
The update should be as simple as doing Get and then Update.
var recToUpdate = db.Get<Record>(1); // record with primary key of 1.
recToUpdate.Value = "100"; // instead of 50
db.Update(recToUpdate);
It executes the update line fine, but the db still holds the older value of 50 instead of 100, when I run the app again.
Is my approach totally wrong?
If you are including an existing db in your app bundle, you cannot write to it. The app bundle is read only - this is an iOS security measure. In order to write to your db, you will need to move it to a user writable folder.
// in your app startup
string rootPath = "/mydb.db";
string userPath = Path.Combine(Environment.GetFolderPath (Environment.SpecialFolder.MyDocuments), "mydb.db";
// if userdb does not exist, copy it from the app bundle
if (!File.Exists(userPath)) {
File.Copy(rootPath, userPath);
}
When you want to actually access your db, you just use the db access code you already have, but be sure you are using the user writable path.
var db = new SqliteConnection (userPath);
Finally, if your db is read-only and will not be updated by the user, you can leave it in the app bundle and don't need to make a writable copy.
try with
recToUpdate.Value = "100"; // instead of 50
int i = db.Update(recToUpdate);
//check number of rows updated (i), db.Update() returns number of rows updated...
//or first try with recToUpdate.Value = 100; and see the number of rows affected + use try/catch if an error appears.

Saving an entity to the DB in WinForms

I've looked at so many posts about this, but still haven't found the solution:
I'm using a winforms app that uses EntityFramework (6?). When I load the form I can read from the DB using the context (Entities). However, when I savechanges after adding a new entity, it doesn't persist to the db.
var c = new Card { Name = tbName.Text, Quantity = int.Parse(tbQuantity.Text) };
dbContext.Cards.Add(c);
dbContext.SaveChanges();
The dbContext is setup in the form constructor and is an instance of "LiquorTrackEntities".
LiquorTrackEntities dbContext;
public Form1()
{
InitializeComponent();
dbContext = new LiquorTrackEntities()
Reading from the db works:
var cards = dbContext.Cards.ToList();
I do this stuff all the time in asp.net MVC, but it isn't working in WinForms.. is there something special I have to do in winforms? I also know about the normal "using (var db = new LiquorEntitiesEntities())" convention, but I just want to get this functioning before I worry about convention.
Any ideas?
Just tried this to no avail:
var c = new Card { Name = tbName.Text, Quantity = int.Parse(tbQuantity.Text) };
dbContext.Cards.Attach(c);
dbContext.Entry(c).State = EntityState.Added;
dbContext.SaveChanges();
Just tried creating a new EDMX using EF5 instead.. same problem.
UPDATE:
SaveChanges does return a 1 when after adding a card. It stays in the context (if I reload my cards from the context, the new one is there..) but never makes it to the database.

Linq2SQL not updating record on SQL Azure

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?

How to save changes in Linq-to-SQL?

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))

Categories