4

I'm using Entity Framework (DbContext with database first) with MVC. When user save from a form, I have a condition in the controller that send the entity to the update of insert method depending of some internal flag of mine.

When sending entity to the update method, I flag it to modified using context.Entry(myEntity).State = EntityState.Modified;, I call saveChanges() and everything work well.

When sending the entity to the insert method, I flag it to added using context.Entry(myEntity).State = EntityState.Added; but when calling saveChanges() I receive error about 2 fields that are required...

The problem is that thoses 2 fields are not empty and they effectively contain valid data just before saving... I have even try to force new values to thoses 2 fields just before saving but same error.

It may be usefull to mention that I'm using Devart DotConnect For PostgreSQL as db provider.

Any idea how to debug this problem?

EDIT:

Here is the error:

Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.

When looking for this EntityValidationErrors I receive the 2 following specific errors:

The flg_actif field is required

The user_creation field is required

As mentionned before, those fields are filled with data just before saving so I don't understand what is happening.

I'm using EF v4.0.30319 (system.data.entity=> v4.0 and EntityFramework=> v4.4)

EDIT2: Just to clarify a little bit more: The entity I'm trying to insert already exist in database. The form show the data of this database row. When saving, I decide if I update the row (this work well) but sometime, I need to insert the edited row as a new register instead of updating it to keep an history of the change in database.

Community
  • 1
  • 1
Etienne Desgagné
  • 3,102
  • 1
  • 29
  • 36
  • 1
    Start by having a look what is sent across the wire to the database server. Be useful to include the text and stack trace of the error also. – Pete - MSFT Nov 02 '12 at 00:38
  • You can get a query log from the PostgreSQL end by setting `log_statement = 'all'` in `postgresql.conf` ; alternately, enable SQL logging in Entity Framework. The versions of the tools you're using would also be helpful. BTW, please always include the *full, exact text of any error messages*. – Craig Ringer Nov 02 '12 at 01:51
  • I have setted the log for PostgreSQL but no query is sent to database as the saveChanges() fail. – Etienne Desgagné Nov 02 '12 at 13:44
  • This is an error generated by EF as it notes the fields as required, but not set. As such it stops there, and won't actually send out the SQL. I suggest you check via break points / Intellitrace exactly what these variables are set to within the context before you save the changes. – Nick Nov 02 '12 at 13:52
  • I put a break point on the context.saveChanges() statement. drilling down this context => myEntity => Results View => ... I can see all the fields of my entity and thoses two fields contains the values: true and "etides" as the first one is a bool and the second one is a string. – Etienne Desgagné Nov 02 '12 at 14:01

1 Answers1

2

Could you verify if the EntityKey property is set or null on the items you are trying to save?

If it already has a key, the context is already aware of the item, and you should use Attach instead of setting the state to added manually.

EDIT: To summarise the point from below. It looks like what you are doing is inserting a new copy of a row already associated with a context. That is almost certainly your problem. Try creating a fresh object based on your original row (i.e. copy the variable values or use a copy constructor), then add that new object.

Additionally, you should not need to set the state manually on a newly added object. You are trying to force the state here because the context doesn't see that item as a new one.

Nick
  • 2,285
  • 2
  • 14
  • 26
  • There is no EntityKey property on my entity and when trying to Attach the entity I receive the error: System.InvalidOperationException: A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship. – Etienne Desgagné Nov 02 '12 at 14:17
  • Ok, the lack of key confirms it's a new item to the context. Just out of interest, where are you actually adding the item to the set? – Nick Nov 02 '12 at 14:24
  • I fact I don't say that the EntityKey is null but instead that I don't see anywhere this EntityKey property... I'm using DbContext and not ObjectContext... I think this may be the reason... – Etienne Desgagné Nov 02 '12 at 14:40
  • This entity is created as a parameter of my controller when user save form. I'm adding the item to the set like this: context.MyEntities.Add(myEntity); after that I call saveChanges() that fail. Instead of using .Add I have tried context.Entry(myEntity).State = EntityState.Added; but same result. – Etienne Desgagné Nov 02 '12 at 14:45
  • Ok, at that point the state should be handled automatically, is there a reason you set the state manually? – Nick Nov 02 '12 at 14:49
  • I'm just following the basic MVC/EF tutorial... The only difference is that I'm trying to insert a row from an entity already existing that has been modified in the form... I just don't want to lose the original row by making a copy of it... – Etienne Desgagné Nov 02 '12 at 14:52
  • I set the state manually just to try because using .Add was not working. Anyway, both ways fails with same error... – Etienne Desgagné Nov 02 '12 at 14:53
  • Ah hah... ok, so the most likely cause of your problem is that the context is seeing that entity as associated with a different context, or instance of the context. Your best bet: Make a copy of the object (use a copy constructor) you want to insert that so it's 'fresh' and add that. – Nick Nov 02 '12 at 14:53
  • Not really sure how to do correctly that copy... I try to detach the entity first (context.Entry(myEntity).State = EntityState.Detached;) and Add it after but same error when saving... – Etienne Desgagné Nov 02 '12 at 15:41
  • If you are adding a new row, you shouldn't be detaching and re-attaching because it's a recipe for problems. What you want is a new row, based of an existing one. Row r = new row(), r.prop1 = oldRow.prop1 etc, context.add(r) – Nick Nov 02 '12 at 15:44
  • 1
    Thanks a lot Nick. it work when creating explicitly a new entity. – Etienne Desgagné Nov 15 '12 at 14:11