I am using MYSql database and Entity Framework as an ORM to it.
I have two tables:
table A and table B. Table A has a field which is a foreign key on some field from table B.
And the constraints to this key are: Update:Restrict, Delete:Restrict
So the situation:
when I try to delete a record from table B everything works fine
when I try to delete a record from table B and this record is referenced by another record from table A it does nothing and it is expected ofc.
when I try to delete a record from table B, which is referenced, it does nothing but if I after this try to delete a record from table A which was referencing that record from table B it appears that both records are deleted. But only the record from table A should be deleted.
So I assume that there is some kind of caching which caches the unsuccessfull query and tries to execute it when possible.
In some time I`ll try to post some pictures if my words are very fuzzy =)
Ah, and the question: can anyone clear this situation?)
Resolved this issue.
No caching or such things =)
Just entity object which I tried to delete was marked with EntityState.Deleted and despite the exception throwed the state wasn`t rollbacked.
Related
I have related tables in SQL (one to many). One is employees table and the other is the record table for day offs, When i want to delete one employee I get the below error in C#:
SqlException: The DELETE statement conflicted with the REFERENCE constraint "FK_Izin_Personel". The conflict occurred in database "Inotra", table "dbo.Izin", column 'personelid'.
The statement has been terminated.
I tried changing insert and update actions to cascade and that worked for other tables, but it also deletes from both tables when I delete from one.
So my question is: How can I remove from only one of the two related tables, so that the records of other table remain unchanged?
When you delete from the employee table, then you must also delete all related records in the record table.
Relationships ensure data integrity, without them, data may be incomplete or incorrect. In your case you need to remove the relationship between the tables("FK_Izin_Personel"), then there will be no error.
i have a problem with inserting data in my database.
I have three tables which i created with the heideSQL and linked the three tables with foreign key. 1st table (many to one) 2nd table (one to many) 3rd table. when i try now to insert new data with db.SaveChanges(); it throws an insert exception which tells me that he cant match the foreign key because eventually two or more objects have the same primary key. but i just have one ID-Field in each table which is AUTO_INCREMENT. i use the ID-Field of the 2nd table to link in the first and the 3rd one.
could the problem be that everytime i create the new database object for insert that i always add the same object which belongs to the 2nd table to the db-object even it stays the same. same with the object for the 1st table. might that be the mistage and how can i fix this?
the code and the pic of the database are attached. i hope it helps to understand my problem.
Cheers, Only3lue
db.zeichnungs.Add(zeichnung);
db.projekts.Add(projekt);
db.tags.Add(tag);
}
try
{
db.SaveChanges();
} ...
I have two tables that are basically link tables.
So one looks like this;
QueueId
TaskId
the two columns link to a Queues table and a Tasks table.
There is no primary key and i don't believe I need one.
I so try to import it into my .EDMX and I get the warning that
the table does not have a primary key defined but that it's been inferred as a read only table.
Also, the table doesn't show up in the Diagram and there is no model created for it.
I added a primary key and then got errors in my code.
I deleted all tables and did it all again and still the same thing happens with this one table.
The second table that is virtually identical has the same error but does appear in the diagram.
How do I get the first table to show in the diagram and not be read only because I need to delete the associations from time to time.
Thanks
Entity Framework doesn't need association table in the model to work with it.
There should be two navigation properties on either side of the relation - Task has ICollection<Queue> and Queue has ICollection<Task>. To remove association between specific task and queue you either find queue and remove that thask from it's collection, or do the reverse.
Relatively simple problem.
Table A has ID int PK, unique Name varchar(500), and cola, colb, etc
Table B has a foreign key to Table A.
So, in the application, we are generating records for both table A and table B into DataTables in memory.
We would be generating thousands of these records on a very large number of "clients".
Eventually we make the call to store these records. However, records from table A may already exist in the database, so we need to get the primary keys for the records that already exist, and insert the missing ones. Then insert all records for table B with the correct foreign key.
Proposed solution:
I was considering sending an xml document to SQL Server to open as a rowset into TableVarA, update TableVarA with the primary keys for the records that already exist, then insert the missing records and output that to TableVarNew, I then select the Name and primary key from TableVarA union all TableVarNew.
Then in code populate the correct FKs into TableB in memory, and insert all of these records using SqlBulkCopy.
Does this sound like a good solution? And if so, what is the best way to populate the FKs in memory for TableB to match the primary key from the returned DataSet.
Sounds like a plan - but I think the handling of Table A can be simpler (a single in-memory table/table variable should be sufficient):
have a TableVarA that contains all rows for Table A
update the ID for all existing rows with their ID (should be doable in a single SQL statement)
insert all non-existing rows (that still have an empty ID) into Table A and make a note of their ID
This could all happen in a single table variable - I don't see why you need to copy stuff around....
Once you've handled your Table A, as you say, update Table B's foreign keys and bulk insert those rows in one go.
What I'm not quite clear on is how Table B references Table A - you just said it had an FK, but you didn't specify what column it was on (assuming on ID). Then how are your rows from Table B referencing Table A for new rows, that aren't inserted yet and thus don't have an ID in Table A yet?
This is more of a comment than a complete answer but I was running out of room so please don't vote it down for not being up to answer criteria.
My concern would be that evaluating a set for missing keys and then inserting in bulk you take a risk that the key got added elsewhere in the mean time. You stated this could be from a large number of clients so it this is going to happen. Yes you could wrap it in a big transaction but big transactions are hogs would lock out other clients.
My thought is to deal with those that have keys in bulk separate assuming there is no risk the PK would be deleted. A TVP is efficient but you need explicit knowledge of which got processed. I think you need to first search on Name to get a list of PK that exists then process that via TVP.
For data integrity process the rest one at a time via a stored procedure that creates the PK as necessary.
Thousands of records is not scary (millions is). Large number of "clients" that is the scary part.
I'm using ADO.NET with a strongly typed dataset in C# (.NET 3.5). I want to insert a new row to two tables which are related in an 1:n relation.
The table Attachments holds the primary key part of the relation and the table LicenseAttachments holds the foreign key part.
AttachmentsDataSet.InvoiceRow invoice; // Set to a valid row, also referenced in InvoiceAttachments
AttachmentsDataSet.AttachmentsRow attachment;
attachment = attachmentsDataSet.Attachments.AddAttachmentsRow("Name", "Description");
attachmentsDataSet.InvoiceAttachments.AddInvoiceAttachmentsRow(invoice, attachment);
Of course when I first update the InvoicesAttachments table, I'll get a foreign key violation from the SQL server, so I tried updating the Attachments table first, which will create the rows, but will remove the attachment association in the InvoiceAttachments table. Why?
How do I solve this problem?
On the relation between the tables, ensure that the "Both Relation and Foreign Key Constraint" is selected and "Update Rule" is set to "Cascade". Combined with the "Refresh the data table" option on the adapter, after you insert your parent row, the updated ID will "Cascade" down the relationships, preventing foreign key violations in your dataset. Your child tables will then be ready to properly insert into the database.
Some things to try:
When you configure the tableadapter, did you click on advanced options, and check on "refresh data table" so that it will retrieve the identity column value?
For me sometimes I either forgot to check it, or it didn't save the configuration correctly because I didn't have my table identity increment/seed set for whatever reason. Are you using identity increment on the table?
You might also consider just re-creating the adapters for those two tables.
Usually when I go back over everything I find it was something stupid on my part.
Lastly, you might consider calling update on the Primary table, then manually grab the primary key value and manually set the value when you insert the child record. If that doesn't make sense let me know and I will post code.
You need to tell your parent table's table-adapter to refresh the
data-table after update operation.
This is how you can do that.
Open the properties of ProgramUserGroupTableAdapter -> Default Select Query -> Advnaced options. and Check the option of Refresh the data table. Save the adapter now. Now when you call update on table-adapter, the data-table will be updated [refreshed] after the update operation and will reflect the latest values from database table. if the primary-key or any coloumn is set to auto-increment, the data-table will have those latest value post recent update.
Now you can Call the update as pug.Update(dsUserGroup.ProgramUserGroup);
Read latest values from the ProgramUserGroup coloumns and assign respective values into the child table before update. This will work exactly the way you want.
alt text http://ruchitsurati.net/files/tds1.png