An error occurred while entries were being updated. - sql

First of all, Sorry for the bad english.
I'm working on a university project with EF 4.0. Everytime i want to delete an entity item from the collection i get the error : "An error occurred while entries were being updated."
I have foreign keys.
I can't post images because i justa have 1 point of rep, so i can't show you de diagramas.
private void Elimina_Pais_btn_Click(object sender, RoutedEventArgs e)
{
int IdPaisABorrar = ((Pais)Tabla_Paises_DataGrid.SelectedItem).Id;
MundialEntities db = new MundialEntities();
Pais PaisABorrar = db.Paises.Single(p => p.Id == IdPaisABorrar);
if(PaisABorrar != null)
db.Paises.Remove(PaisABorrar);
db.SaveChanges();
UpdatePaises();
}
Inner Exception {"The DELETE statement conflicted with the REFERENCE constraint \"FK_Pais_Visita\". The conflict occurred in database \"Mundial\", table \"dbo.Partido\", column 'IdVisita'.\r\nThe statement has been terminated."}
Thank You very Much

You are trying to delete (remove) a record that is still being used in another table. So unless cascade delete can be setup on this record type, you will need to remove the other record/s at the sametime or before.

Either you can you cascade delete in your migration table or you can load the entities to delete them
Something like (believing that you have some table called as Visita (replace it with your table name)
Pais PaisABorrar = db.Paises
.Include(p => p.Visita)
.Single(p => p.Id == IdPaisABorrar);
The statement Include(p => p.Visita) will load all the related entries and then they will be deleted by call db.Paises.Remove(PaisABorrar);
NOTE: If this had helped you then dont forgot to vote it up and mark it as answer

Related

The MERGE statement conflicted with the CHECK constraint - Entity framework

I have the following code updating the place table with entity framework. Place table has Check constraint on column SequenceNumber. ([SequenceNumber]>=(1))
I am trying to update the table with entity framework but when i try to update it gives me error:
SqlException: The MERGE statement conflicted with the CHECK constraint "CK_Places_SequenceNumber". The conflict occurred in database "XXX", table "dbo.Places", column 'SequenceNumber'.
Below is the code. Just to try I even commented SequenceNumber assignment to avoid the update but i think it depends on the underlying state of entity as well.
var places = placeDtos.Select(x => new Place
{
PlaceId = x.PlaceId,
Name = x.Name,
SequenceNumber = x.SequenceNumber,
PlaceAreaId = areaId,
PlaceInterestPlaces = x.PlaceInterests?.Select(d => new PlaceInterestPlace
{
PlaceId = x.PlaceId,
PlaceInterestId = d.PlaceInterestId
})?.ToList()
})?.ToList();
_dbContext.Places.UpdateRange(desks);
await _dbContext.SaveChangesAsync();
Can someone help in making me understand whats the problem here? Thanks.

How to avoid System.Data.Entity.Infrastructure.DbUpdateException when doing migration

I have one database and I need to do migration, in other words I need to move the data to another database. I have used EF, and generated automatically the classes with EDO. The problem occures at newDb.SaveChanges()
Here is my code:
var oldDb = new oldBAEntity();
var newDb = new NewDbContextEntities();
var query2 = oldDb.R_ClaimHistory.ToList();
foreach (var sourceObj in query2)
{
ClaimComment targetobj = new ClaimComment();
targetobj.ClaimId = (int)sourceObj.IdClaim;
targetobj.Comment = sourceObj.HistClaimDescription;
targetobj.UserCreated = (int)sourceObj.IdUserCreated;
targetobj.DateCreated = sourceObj.DateCreated;
newDb.ClaimComments.Add(targetobj);
}
newdb.SaveChanges();
When I run it, I am getting this error :
System.Data.Entity.Infrastructure.DbUpdateException
InnerException :
The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_ClaimComments_Claims\". The conflict occurred in database \"Toni-Bank-DB\", table \"dbo.Claims\", column 'ID'.\r\nThe statement has been terminated.
You appear to be attempting to insert a new ClaimComment when the Claims.ID does not exist (or does not match).
You will need to re-order your code to ensure all FKs exist before attempting to add a record which has the constraint defined.
Before inserting to ClaimComment table you need to have corresponding ClaimId in Claim table. So First make sure Master table data are inserted and then go for child tables.

SQL Delete Query Foreign Key constraint

I am trying to Delete record with primary key as foreign key in two tables. Everytime I try to run the query it gives me this error:
Query:
DELETE FROM BusinessPlus_Post
FROM BusinessPlus_Post
INNER JOIN BusinessPlus_PostImage ON BusinessPlus_Post.Post_ID = BusinessPlus_PostImage.BusinessPlusPost_ID
INNER JOIN BusinessPlus_PostTag ON BusinessPlus_Post.Post_ID = BusinessPlus_PostTag.BusinessPlusPost_ID
WHERE
(BusinessPlus_Post.Post_ID = 3)
AND (BusinessPlus_PostImage.BusinessPlusPost_ID = 3)
AND (BusinessPlus_PostTag.BusinessPlusPost_ID = 3)
Error:
The DELETE statement conflicted with the REFERENCE constraint
"FK_BusinessPlusPostImage". The conflict Occurred in database
"BusinessPlus_AdminPanel_Database", table
"dbo.BusinessPlus_PostImage", column 'BusinessPlusPost_ID'. The
statement was terminated.
Right now, you are only stating that you want to delete the BusinessPlus_Post record, but not the BusinessPlus_PostImage and BusinessPlus_PostTag records. This would lead to problems, as we then would have 'orphan' PostImage and PostTag records with no corresponding Post records.
Apparently, it is not possible to delete from multiple tables in SQL Server (it is supported in MySQL, for example).
You have to split your queries, and delete from the 'child' tables first:
DELETE FROM BusinessPlus_PostImage
WHERE BusinessPlusPost_ID = 3
DELETE FROM BusinessPlus_PostTag
WHERE BusinessPlusPost_ID = 3
DELETE FROM BusinessPlus_Post
WHERE Post_ID = 3
Error: The DELETE statement conflicted with the REFERENCE constraint
"FK_BusinessPlusPostImage". The conflict Occurred in database
"BusinessPlus_AdminPanel_Database", table
"dbo.BusinessPlus_PostImage", column 'BusinessPlusPost_ID'. The
statement was terminated.
Error denotes that you have data referencing the foreign ,hence you cannot delete.
Delete the datas in BusinessPlus_AdminPanel_Database table
dbo.BusinessPlus_PostImage, column BusinessPlusPost_ID ,and then try delete

NHibernate SaveOrUpdate without primary key

The Situation
I've got a database table that is mapped via NHibernate (3.3.3-SP1). The application is running on .NET4.0 and the mapping is done via FluentNHibernate (1.4.0).
CREATE TABLE Movies
(id INT PRIMARY KEY,
yearPublished DATETIME NOT NULL,
name NVARCHAR(500) NOT NULL,
description NTEXT NOT NULL)
The data would be something like this:
id | yearPublished | name | description
---+---------------+------------------------+--------------------------------------------
1 | 1968 | 2001: A Space Oddyssey | An epic drama of adventure and exploration
The Problem
I'm creating new entities of this table and want to avoid adding more than one entity for the same real world thing. I know that there is Session.SaveOrUpdate and that there is also a way to make it work with composite and natural ids but that's not really what I want since my entities actually have a primary key and I really only need the composite key for making sure that no duplicates are in the DB.
var movie = new Movies
{
yearPublished = 1968,
name = "2001: A Space Oddyssey",
description = "An awesome journey to Jupiter"
};
// Behavior right now:
// Adds a new movie besides the fact that
// the movie is already in the database
// but now has two entries
session.SaveOrUpdate(movie);
Assert.IsTrue(movie.id == 2 && movie.description == "An awesome journey to Jupiter");
// What I really want is to be able to define what
// makes an object unique other than the primary key;
// in this scenario it should look for a combination
// of "yearPublished" and "name"
session.MyAwesomeSaveOrUpdate(movie);
Assert.IsTrue(movie.id == 1 && movie.description == "An epic drama of adventure and exploration");
Is this functionality in place in NHibernate (e.g. through a custom mapping) or do I have fetch the candidates from the DB and do it by hand?
Thanks!
I solve this by adding a unique constraint on the natural key fields in the database and using an exception converter to convert the SQL Server exception into one my application can handle.
public class SqlServerExceptionConverter : ISQLExceptionConverter
{
public Exception Convert(AdoExceptionContextInfo adoExceptionContextInfo)
{
var sqlException = adoExceptionContextInfo.SqlException as SqlException;
if (sqlException != null)
{
// 2601 is unique key, 2627 is unique index; same thing:
// http://blog.sqlauthority.com/2007/04/26/sql-server-difference-between-unique-index-vs-unique-constraint/
if (sqlException.Number == 2601 || sqlException.Number == 2627)
{
// my custom exception
return new UniqueKeyException(sqlException.Message, sqlException);
}
}
return adoExceptionContextInfo.SqlException;
}
}
Another approach I can think of is to query the database for a matching record before the insert but that's not foolproof because a record could be inserted between the select and your insert.

"Parent Key Not Found" although it exists (within the TX)

I just observed a strange behaviour (of course Oracle is probably supposed to behave this way, but it didn't fit in my world view yet):
I try to insert two rows into a parent and a child table, both within the same transaction:
INSERT INTO V_Parent (ID, Name) VALUES (777, 'Hello World');
INSERT INTO T_Child (ParentID, Name) VALUES (777, 'Foo Bar');
The Child table has a (ParentID) references Parent.ID foreign key constraint.
On the second statement Oracle fails with the error message "Parent key not found."
If I disable the FK constraint, it works. I have asserted that the ParentID and the Parent.ID match, and I am 100% sure that the first line is executed successfully before the second one. Further, I have tried to commit each statement, which worked fine.
However, as the prefixes in my code example suggest, the first INSERT is actually done on a view of the parent table. The reason is that I use NHibernate and the mapping uses the view in background (which didn't cause any problems until today).
Q1: Could it be that inserting on a view is deferred by Oracle so that the second statement fails?
Q2: How can I remedy this problem best?
Do I need to define INSTEAD OF triggers on the views?
Can I change a setting on the VIEW definition?
Can I change a setting on the FOREIGN KEY definition?
(I must not bend the hibernate mapping to the original table: It's a demand to use the views so changes and/or security issues can be hidden behind the views)
Details: C# WinForms Application - NHibernate - Oracle 10.2 - T_Child: Sooner or later I will use a view for that table, too, it's simply not defined yet.
Edit: More Details according to the comments:
The ID is assigned by NHibernate using an Oracle sequence (<generator class="sequence">), and is part of the INSERT statement as in my example. I also verified that the resulting ID in the table row matches the one NHibernate saved in the mapped object.
The view is defined as a SELECT that JOINS some fields of other tables. However, on insert/update I only change the fields belonging to the main table ("T_PARENT"), and that normally works fine.
The current foreign key constraint is not deferrable, but that shouldn't have any effect because the parent statement is executed before the child statement. *)
*) Hmm... let me think: Since I use an NHibernate session for submitting the SQL queries, could it be that NHibernate executes them in a different order than I told it to?
I'll investigate on that. => It seems so, see my own answer.
This is how the actual code looks like:
ISession session = this.DAOFactory.NHibernateHelper.SessionFactory.OpenSession();
ITransaction tx = session.BeginTransaction();
try
{
// parent.ID == 0
session.SaveOrUpdate(parent);
// parent.ID == 777 (for example)
ISQLQuery query = session.CreateSQLQuery(
"INSERT INTO T_CHILD (PARENT_ID, NAME) VALUES (:parentId, :name)");
query.SetDecimal("parentId", parent.ID);
query.SetDecimal("name", "Foo Bar");
query.ExecuteUpdate(); // Fails with ORA-Exception
tx.Commit();
}
catch (Exception)
{
tx.Rollback();
throw;
}
finally
{
session.Close();
}
You don't need to define an INSTEAD OF trigger if the view is already updateable. Inserting in a view that has a simple relation with its base table will behave as inserting in the base table -- consider:
SQL> CREATE TABLE t (a NUMBER, b NUMBER, c NUMBER);
Table created
SQL> CREATE VIEW v AS SELECT a, b FROM t;
View created
SQL> INSERT INTO v VALUES (1,2);
1 row inserted
SQL> SELECT * FROM t;
A B C
---------- ---------- ----------
1 2
For your insert problem, you probably have a BEFORE INSERT trigger on the base table (with the id colomn filled by a sequence).
I've got it.
As stated in the update to my question, it seems that the NHibernate session mixes the order of the SQL statements. To remedy this, I added the following line of code:
session.SaveOrUpdate(parent);
session.Flush();
// (...)
query.ExecuteUpdate();