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

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.

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.

Remove duplicate lines from SQL Server table

Someone deployed a SQL table with the schema
ConfigOptions
name VARCHAR(50)
value VARCHAR(50)
and the following logic for saving options:
int i = ExecuteNonQuery("UPDATE ConfigOptions SET value=#value WHERE name=#name");
if(i==0) i = ExecuteNonQuery("INSERT INTO ConfigOptions (name,value) (#name,#value)");
We now saw that this table is littered with duplicates, and we want to change this.
As far as I can tell, the logic is: whenever the UPDATE affected zero rows, another row is inserted. If I am not mistaken, this can be caused by:
a row by the name of #name does not exist or
the row exists, but already contains value #value
So, all rows with same name should be full duplicates. If now, something is completely wrong (and behaviour may be undefined).
Now I have to fix this problem of duplicates, so I want to add a PK on name. Before I can do this, I have to remove all rows with duplicate names, only keeping one of each.
In the installer (only the installer is allowed to change schema), I only have SQL queries at hand, so I can't do it with C# logic:
Dictionary<string, int> dic = new Dictionary<string, int>();
SqlDataReader sdr = ExecuteReader("SELECT name,COUNT(value) FROM ConfigOptions GROUP BY name HAVING COUNT(value)>1");
while (sdr.Read()) dic.Add(sdr.GetString(0), sdr.GetInt32(1));
sdr.Close();
foreach (var kv in dic) {
AddParameter("#name", System.Data.SqlDbType.VarChar, 50, kv.Key);
ExecuteNonQuery("DELETE TOP " + (kv.Value - 1) + " FROM ConfigOptions WHERE name=#name");
}
ExecuteNonQuery("ALTER TABLE program_options ADD PRIMARY KEY (name)");
Is there a way to put this into SQL logic?
Using %%physloc%%, the phys(ical) loc(ation) of the row, should do the trick:
DELETE FROM ConfigOptions
WHERE %%physloc%% NOT IN (
SELECT MIN(%%physloc%%)
FROM ConfigOptions
GROUP BY name);
After this cleanup, you can add the primary key to the table.
NOTE: this will leave you with only one row for every name. If the value column is different in two records with the same name, you will lose the newest record. If you want to change this, use GROUP BY name, value.

An error occurred while entries were being updated.

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

SQL Merge is not adding to table

I'm trying to merge a temporary table, populated with data from a c# application with a table in my SQL database.
Having read through some articles it seems that SQL Merge should be the most appropriate option and it works great when I'm updating or deleting groups of entries from the database.
My problem is that I'm unable to add a new row of data where the foreign keys don't match what is already in the database table, but instead it is just removing the rows in the database and replacing the new ones in the temporary table.
I have two foreign keys referenced in the table FirstDBTableID and SecondDBTableID.
This is my SQL so far:
ALTER PROCEDURE [dbo].[SP_UpdateTable]
#TempTable as TempTableType READONLY
AS
BEGIN
MERGE dbo.Table AS target
USING #TempTable AS source ON target.FirstDBTableID = source.FirstDBTableID
AND target.SecondDBTableID = source.SecondDBTableID
WHEN MATCHED THEN
UPDATE SET target.Provider = source.Provider, target.Value = source.Value, target.Quantity = source.Quantity
-- value doesn't exist in the target table, so add it
WHEN NOT MATCHED BY TARGET THEN
INSERT (FirstDBTableID, SecondDBTableID, Provider, Value, Quantity)
VALUES (source.FirstDBTableID, source.SecondDBTableID, source.Provider, source.Value, source.Quantity)
-- value doesn't exist in the source table, so delete from target
WHEN NOT MATCHED BY SOURCE THEN
DELETE;
END
Have a missed statement? Maybe SQL Merge isn't going to work here? If I haven't made it clear please ask me questions.
Thanks in advance.

Webmatrix - Creating two tables with the primary key from one

I currently have the following SQL statement which creates an entry in my database, and auto creates the primary key. This works fine:
if (IsPost){
var sql = "INSERT INTO Property_Info (PropertyName) VALUES (#0)";
db.Execute(sql, Request["propertyname"]);
}
What I also need to do on the same page, is insert a record into a different table, using the primary key created in the above statement. is this possible, or will i need to do this on a separate page?
Yep, you can get the database ID you created with db.GetLastInsertId() and use that as a parameter in your next query.
http://msdn.microsoft.com/en-us/library/webmatrix.data.database.getlastinsertid(v=vs.111).aspx
I've found that you are best off casting it to an int too, so immediately after your db.Execute() line, try this:
int newId = (int)db.GetLastInsertId();