MVC 5 EF 6 Insert Multiple Rows SaveChanges - asp.net-mvc

I am trying to insert multiple rows using the following code. SaveChanges() works for the first record but if fails when it tries the next one. My guess is that each time it is trying to insert all records. Not sure if this is correct or not, and if it is correct how can I change the code to make it correct. Following is my code:
Contrroller:
foreach(var m in pms)
{
_pmService.AddPms(m);
}
And in _pmService.AddPms:
_pmRepository.Add(pm);
_pmRepository.SaveChanges();
_pmRepository.Add (actually this is from BaseRepository and pmRepository extends this Base)
_ctx.Set<T>().Add(entity);
Finally, here is my SaveChanges() (again this is also from BaseRepostiroy)
_ctx.ChangeTracker.DetectChanges();
return _ctx.SaveChanges();
So in controller, I am looping through each entry, and then calling Add. The Add in service is calls Add in BaseRepository and then it does the SaveChanges(). For first record it works without any issues but 2nd record onwards it fails. And following is the error:
"Saving or accepting changes failed because more than one entity of type XXXXXXXXXXXXX have the same primary key value. Ensure that explicitly set primary key values are unique. Ensure that database-generated primary keys are configured correctly in the database and in the Entity Framework model. Use the Entity Designer for Database First/Model First configuration. Use the 'HasDatabaseGeneratedOption\" fluent API or 'DatabaseGeneratedAttribute' for Code First configuration."
And I am using DatabaseFirst approach.

I found the answer it is with StoreGeneratedPattern. I had to set this Identity in edmx file for the primary key field and it worked.
StoreGeneratedPattern="Identity"

Related

Is it possible to make Entity Framework insert primary key that I given?

I forced to work with database where tables haven't auto increment. And I can't alter it. I want to insert entity using Entity Framework. I create an object of this entity and manually set it's Id field (primay key) and then make Add and SaveChanges. But I see in log, that EF clear the value of DbParameter for Id field. Is there any solution for this?
You can add an annotation of fluent configuration to tell EF the keys are manual. See Entering keys manually with Entity Framework. You could also add a custom convention to handle globally: Convention for DatabaseGeneratedOption.None

How does Breeze handle database column defaults?

I can't find any info about this in the documentation, so I will ask here. How does breeze handle database column defaults? I have required columns in my database, but there are also default static values supplied for these in the database column definitions. Normally, I can insert null into these columns, and the new records will get the default. However, breeze doesn't seem to be aware of database column defaults, and the entities that have null in these columns fail validation on saving.
Thanks,
Mathias
Try editing the edmx xml by adding StoreGeneratedPattern = "Computed" attribute to the column with default value in the DB.
Edit:
Actually, before doing editing the xml, try setting the StoreGeneratedPattern property to Computed in the model editor itself.
Update:
This was fixed in Breeze 1.4.6 ( or later), available now.
Original Post:
There is currently in a bug in Breeze that should be fixed in the next release, out in about week. When this fix gets in then breeze will honor any defaultValues it finds in the EntityFramework data model.
One problem though is while it is easy to get 'defaultValues' into a Model First Entity Framework model via the properties editor, it's actually difficult to get it into a Code First EF model, unless you use fluent configuration. Unfortunately, EF ignores the [DefaultValue] attribute when constructing Code First model metadata.
One workaround that you can use now is to poke the 'defaultValue' directly onto any dataProperty. Something like:
var customerType = myEntityManager.metadataStore.getEntityType("Customer");
var fooProperty = customerType.getProperty("foo");
fooProperty.defaultValue = 123;

Entity Framework complaining about required fields when saveChanges even if valid data are setted

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

Entity Framework 4 Change Audit

I have a web application using EF4. I am somewhat new to EF and now trying to implement change Audit.I tried to do this by trapping the SavingChanges event of the Context Class as below
partial void OnContextCreated()
{
this.SavingChanges += new EventHandler(TicketContainer_SavingChanges);
}
So the event handler accesses the changed records by the following
this.ObjectStateManager.GetObjectStateEntries(
EntityState.Added | EntityState.Modified);
This works fine and I am creating column level audit for selected tables. Every table/entity has an ID field which is an identifier with columnName="ID". So in my audit routine I simply accesses data from column with name "Id" to get the ID of audited record.
The problem I face is during insert . The new record has no ID yet as it is an identity column in the database and is always 0.
One solution I can think of is using GUID for all Ids.But is there a way to implement this using standard int32 Identity Ids?
thanks
When we insert data through EF the identity column is not generted while insertion. To get the Id of Identity columns we have to insert the data first then only we can get the Id of coulmn.
please go through the below which might be helpful to you.
http://www.codeproject.com/KB/database/ImplAudingTrailUsingEFP1.aspx
I don't now how many entities you have but in our own implementation of audit tracking we created a specific audit entity for each entity so we could link them together trough navigational properties and let the database set the identity keys.
If you use inheritance for your audit entities it's quit easy to query them.
Hope this helps :)
Identity columns are not generated while insertion. Once data is inserted then only you can get identity column data in EF. So, you can try some work around by getting Id after insertion and then populating audit table with that Id.

Linq to SQL replacing related entity

I have a Client entity and PostCode entity in Linq to SQL model. The Clients table in database contains client_postcode column which is a FK column to postalcode column in PostCode table, which is a varchar column primary key for PostCode table.
When updating Client, in my code I do this
// postcode
updating.PostCode = (from p in ctx.PostCodes
where p.postalcode.Equals(client.PostCode.postalcode)
select p).First();
where client object is provided from ASP.NET MVC View form. This code seems to set the PostCode related entity fine. But when calling SubmitChanges() I receive the following exception:
Value of member 'postalcode' of an object of type 'PostCode' changed. A member defining the identity of the object cannot be changed. Consider adding a new object with new identity and deleting the existing one instead.
So I am currently unable to change the related entity. How is that done in Linq to Sql?
UPDATE:
After further review and troubleshooting I found out that the problem is in ASP.NET MVC UpdateModel() call. If I call UpdateModel() to update the existing entity with the edited data, something is wrong with the FK assignement for PostCode. If I don't call UpdateModel and do it by hand, it works.
Any ideas what goes wrong in UpdateModel() that it can't set the relationship to foreign key entities correctly?
I am updating this question and starting a bounty. The question is simplified. How to successfully use L2S and UpdateModel() to work when updating items (with related entities as FK) in ASP.NET MVC Edit views?
It seems to me that you are receiving PostCode.postalcode in the http post request.
Based on how model binding works, the UpdateModel call updates .PostCode.postalcode of the model you are passing to it.
Use this overload to include or exclude specific properties.
Wouldn't updating.client_postcode = client.client_postcode; accomplish what you want?
Client.PostCode should be looked up on seek based on client_postocde.
You can not do what you are trying, you cannot change the Postcode like that.
James' idea is in the right direction.
Updatemodel() takes the matching values from the Formcollection
How do these values come in the Formcollection? What are their keys?
basically there are 2 ways in editing an object.
option 1:
all the value names you want to update have corresponding keys in the Formcollection, which leaves you just to call UpdateModel() of the original object. do SubmitChanges()
option 2:
Get the original object, change it's values manually (because the keys dont correspond) and do SubmitChanges()
you are tying to change a link, you cant do that. you can only edit the updating.client_postcode which in this case is a string?
Can you please copy the whole action here? So I can write some code for you without gambling.

Resources