Page 1 of 1
Can't upadte a simple record in the database
Posted: Sun 06 Nov 2011 13:34
by shaharw18
hi,
I'm trying to update a record using dotconnect (or is it linqconnect)...
anyway these are the lines i'm using:
ent.Clips.Attach(updClip);
ent.SubmitChanges();
it seems the database does not get updated.
thanks
Shahar.
Posted: Mon 07 Nov 2011 09:12
by StanislavK
Attaching an entity object to the context enables change tracking for this object. However, as data context has no information concerning the actual status of the attached entity, it supposes that the entity is up-to-date unless you specify that it is not.
To inform the context that an attached entity should be updated, you can, e.g., attach it together with its original state:
Code: Select all
ent.Clips.Attach(updClip, oldClip);
ent.SubmitChanges();
Please tell us if this helps.
Posted: Tue 08 Nov 2011 00:08
by shaharw18
thank you for reply.
ent.Clips.Attach(updClip, oldClip);
ent.SubmitChanges();
updClip is the record I would like to update including the modified field in it.
what would be oldClip?
the entire table ?
I did'nt do a SELECT on the table only a straight update.
what is oldClip?
so you have a sample for your own code lines doing these task?
thanks
Shahar.
Posted: Tue 08 Nov 2011 15:43
by StanislavK
In the sample, 'oldClip' is an entity object with the same fields as 'updClip', except the fields being updated. For example,
Code: Select all
MyEntity oldEntity = new MyEntity() { Id = 10, Column1 = "C1", ColumnToBeUpdated = "Old Value", ... };
MyEntity updEntity = new MyEntity() { Id = 10, Column1 = "C1", ColumnToBeUpdated = "New Value", ... };
ent.MyEntities.Attach(updEntity, oldEntity);
ent.SubmitChanges();
Please tell us if this helps.
Posted: Wed 09 Nov 2011 07:41
by shaharw18
Hi.
Here's the new code I've wrote.
I'm getting now an error message: Row not found or changed.
as you can see I've created a demi clipOrg object which is exactly the same one as "clip". except for a changed field as you wrote I need to have.
--------------------------------------------------------------------------
Db.Clip clip = new Db.Clip();
Db.Clip clipOrg = new Db.Clip();
clip.Id = Convert.ToInt32(id);
clip.Title = title.Text;
clip.Path = path.Text;
clip.Tags = tags.Text;
clipOrg = clip;
clipOrg.Title = "";
ent.Clips.Attach(clip,clipOrg);
clip.Title = title.Text;
ent.SubmitChanges();
Posted: Fri 11 Nov 2011 18:03
by StanislavK
Entity classes are reference types, thus in your sample 'clip' and 'clipOrg' are the same object. Thus, when you attach it like
the entity is still marked as unchanged (and its initial state includes 'Title' equal to an empty string).
When updating an entity, LinqConnect checks all its fields by default. In particular, it generates the condition like "Title = '' " in the WHERE part of the update statement. Unless 'Title' is an empty string in the database, this update will fail, leading to the exception you are getting.
To resolve the problem, you can do one of the following:
- make 'clipOrg' a memberwise copy of the 'clip' object (instead of assigning 'clip' to it);
- attach 'clip' and then modify its 'Title':
Code: Select all
ent.Clips.Attach(clip);
clip.Title = title.Text;
ent.SubmitChanges();
Feel free to contact us if anything is unclear.
Posted: Fri 11 Nov 2011 19:54
by shaharw18
thanks for the reply.
what you've wrote is exactly what I"ve done except for the membership.
I'm not familiar with that definition. so, please help.
how do I make clipOrg a membership of clip?
thanks
shahar.
Posted: Mon 14 Nov 2011 13:52
by StanislavK
Memberwise copy is a new object with the fields equal to the ones of the original object. To create it, you should construct a new Clip object and assign the values from the 'clip' instance to its fields:
Code: Select all
Db.Clip clip = new Db.Clip();
Db.Clip clipOrg = new Db.Clip();
[initialize the 'clip' object]
clipOrg.Id = clip.Id;
clipOrg.Title = clip.Title;
clipOrg.Path = clip.Path;
clipOrg.Tags = clip.Tags;
[copy other properties (if any) from 'clip']
Otherwise, you can attach the 'clip' object having 'old' values, and after that set the 'new' values as shown in my previous post. In this case, the context will track these changes and automatically update the corresponding row in the database on SubmitChanges().
Posted: Mon 14 Nov 2011 18:18
by shaharw18
Hi,
I found the solution which suits me.
var clip = ent.Clips.Single(c => c.Id == Convert.ToInt32(id));
clip.Title = title.Text;
clip.Path = path.Text;
clip.Tags = tags.Text;
ent.SubmitChanges();
I don't like the idea that before each update the application is going to query the database, but it seems like LINQ doesn't have any kind of a reasonable staight through query approach. the solution above, is good enough for me.
thanks for the help.
Shahar.
Posted: Tue 15 Nov 2011 15:04
by StanislavK
Glad to see that the problem was resolved.
LinqConnect does provide the possibility of updating an entity without querying for it first. However, it is necessary to pass the 'old' data of the row being updated to the context to create the proper update statement. Or, it is possible to set the Update Check property of all entity fields to 'Never', in which case the update statement will check for the primary key value only.
However, querying for the entity before updating it is in some sense safer, as this approach reduces the probability of using stale data in update checks.
Posted: Tue 15 Nov 2011 18:05
by shaharw18
I would be happy if you will write down a simple example for an update.
without querying the database first. it's difficult for me to understand the reason for why they did what you described at the first place.
I'd thought that after simple SQL queries I used to do, the LINQ technology won't create "new headaques".
shahar.
Posted: Wed 16 Nov 2011 15:48
by StanislavK
I've sent you a sample project, please check that the letter was not blocked by your mail filter.
In the sample, a detached entity is updated in the following ways:
- by attaching both entity and its original state to the context before updating;
- by attaching the entity first, and then modifying it so that the context can track the changes;
- by attaching the entity as modified; this way needs to set all
update check rules to 'Never'.
Feel free to contact us if anything is unclear.