I have a Profile(as shown in below image) Table Which whenever I try to remove a row from it, I face this error which indicates there is still data in foreign key in Tempprice table which is related to the Id in Lots table .
the problem is when its Lots table turn to Delete , there is still rows in Tempprice which have different Userid but same lotsid that have Ownerid or Winnerid which I want to Delete.
And I don't know how to delete this rows!? or which query is needed?
Database Relationships and Tables:
Code:
while (checkbox.Checked)
{
// Retreive the ID
int ida = Convert.ToInt32(GridView1.DataKeys[row.RowIndex].Value);
// Pass the value of the selected Id(s) to the Delete //command.
//These numbers indicate in which order tables shoulde be deleted
/*1*/
new BLL.LoginBLL().Delete(ida);
/*2*/
new BLL.MessageBLL().Delete(ida);
/*3*/
new BLL.JointBLL().Delete(ida);
/*4*/
new BLL.TemppriceBLL().Delete(ida);
/*5*/
new BLL.LotsBLL().Delete(ida);
/*6*/
new BLL.AuctionBLL().Delete(ida);
/*7*/
new BLL.ProfileBLL().DeleteProfile(ida);
checkbox.Checked = false;
}
ShowUsers();
To delete references, you need to set the relation (by selecting the line connecting the two objects) to Cascade for the End 1 On Delete property.
Then you need to Load the referenced object or collection. Calling Delete in this case, will delete your object and all objects it references.
Related
I have two tables with foreign key relationship (1 to many). How can I do that when I'll remove item from first table, it will delete automatically all values with it's foreign key from second table?
So when I'll remove item from 1 table it will remove all items from 2 table whih NameId = ID of 1 table
Depends on the database management system; with MS SQL Server, you can set a foreign key to "ON DELETE CASCADE" which does exactly what you're asking for.
http://www.techonthenet.com/sql_server/foreign_keys/foreign_delete.php
You could just write a function for that:
public void RemoveWithRelatedEntries(int table1ItemID)
{
using(var db = new dbEntities())
{
// get all entities of table 2
var tab2Entities = db.table2.Where(tab2Ent=>tab2Ent.table1Reference == table1ItemID);
// remove all those entities
foreach(table2Item item in tab2Entities)
{
db.table2.Remove(item);
}
// finally remove entity from table 1
var table1entitiy = db.table1.Find(table1ItemID);
db.table1.Remove(table1entity);
db.Save();
}
}
there are probably more elegant solutions but this was what came first to my mind.
I am having a problem with updating a many to many table that does not exist in the edmx diagram.
QuestionGroups
PK - QuesitonGroupID
Questions
PK - QuestionID
This table does not exist in edmx : I am not able to update this table
QuestionGroupQuestions
PK - QuestionGroupID
PK - QuestionID
Answers
PK - AnswerID
This table I am able to update this table correctly
QuestionAnswers
PK - QuestionID
PK - AnswerID
Here the code
public ActionResult Create(int questionGroupID, QuestionVM questionVM)
{
Mapper.CreateMap<Question, QuestionVM>();
Question question = Mapper.DynamicMap<Question>(questionVM);
if (question.Answers != null)
{
question.Answers = new List<Answer>();
foreach (var answer in questionVM.Answers)
{
var questionAnswerToAdd = db.Answers.Find(answer.AnswerID);
question.Answers.Add(questionAnswerToAdd);
}
}
db.Questions.Add(question);
db.SaveChanges();
var questionGroup = db.QuestionGroups.Find(questionGroupID);
questionGroup.Questions.Add(question);
db.QuestionGroups.Add(questionGroup);
The above code is working. I do not want to update the QuestionGroup table. I just want to update the QuestionGroupQuestions table.
db.Entry(questionGroup).State = EntityState.Unchanged;
db.SaveChanges();
return RedirectToAction("Index", "Question");
}
Before the update there are already 2 existing records
QuestionGroupID, QuestionID
14,1
14,3
When adding a new question I get this error message
{"Violation of PRIMARY KEY constraint 'PK_QuestionGroupQuestions'. Cannot insert duplicate key in object 'dbo.QuestionGroupQuestions'. The duplicate key value is (14, 1).\r\nThe statement has been terminated."}
when mapping tables with many-to-many relation(QuestionGroups and Questions), the table which holds related ID's (QuestionGroupQuestions) does not maps to any entity, instead of it the other tow table is mapped to entities with many-to-many association, the association is a collection of instances from each other inside them, and when save any valid changes of these tow tables the EF automatically updates the third table (QuestionGroupQuestions) so it's not need to update QuestionGroupQuestions.
var questionGroup = db.QuestionGroups.Find(questionGroupID);
questionGroup.Questions.Add(question);
//The problem is here that you are adding questionGroup again. comment it and check
//db.QuestionGroups.Add(questionGroup); this cause a error, questionGroup already exists
now if you save the changes to db the QuestionGroupQuestions tables also should get updated.
can someone please help me, how to set parent row when add a new record to bindingsource?
I'm using typed dataset, C# winforms.
my code (add parent and child row):
DataRowView drvParent = (DataRowView)bsParent.AddNew()
drvParent.BeginEdit();
drvParent["ID"] = -1;
drvParent["Name"] = "Parent";
drvParent.EndEdit();
DataRowView drvChild = (DataRowView)bsChild.AddNew();
drvChild.BeginEdit();
drvChild["ID"] = -1;
drvChild.Row.SetParentRow(drvParent.Row);
drvChild["Name"] = "Child";
drvChild.EndEdit();
then when click Save button:
this.Validate();
bsChild.EndEdit();
bsParent.EndEdit();
ParentTableAdapter pAdapter = new ParentTableAdapter();
pAdapter.Update(myDataSet.Parent);
ChildTableAdapter cAdapter = new ChildTableAdapter();
cAdapter.Update(myDataSet.Child);
ID Parent in child is null, why? whereas I already set child's parent row.
thanks
I'm currently working through a similar issue. You want to make sure you have the correct DataRelations between your parent/child tables. This would be in the form of a foreign key in this case. Without the foreign key relationship, I think what's happening is you first do your update on the parent table, an ID is generated for the parent, and then the second update on the child tries to update using -1 which is no longer the foreign key. If you setup the foreign key relationship, after the update on the parent table, the child tables foreign key should be populated with the correct ID.
I have two tables Team_DATA and Driver_PROFILE_DATA in an SQL database. For every driver_profile there can be many teams.
So there's a one-to-many relation on the driver_profile to team_data table. I want to update a team_data foreign key reference in the Driver_profile table of an already existing record to another team_data record that already exists.
I want to do this using entity framework. Here what I want: having a list of teams to select from, finding the record in the team_data table and updating it's FK in the driver_profile appropriately.
So in the code below, the passed parameter is the newly selected team out of the team_data table.
Now I need it to update it FK reference in the Driver_profile table.
Here's what I've got:
UPDATE: Code Updated. It does not save it to database, even if I call savechanges. No errors.
public Driver_PROFILE_DATA GetSelectedTeam(string team)
{
ObjectQuery<Team_DATA> td = raceCtxt.Team_DATA;
ObjectQuery<Driver_PROFILE_DATA> drpr = raceCtxt.Driver_PROFILE_DATA;
var selteam = from t in td where t.Team_Name == team select t;
Team_DATA newteam = new Team_DATA();
newteam = selteam.Select(x => x).First();
// get driver_profile with associated team_data
var data = from a in raceCtxt.Driver_PROFILE_DATA.Include("Team_DATA") select a;
// put it in driver_profile entity
profileData = data.Select(x => x).First();
profileData.Team_DATAReference.Attach(newteam);
return profileData;
}
Entity Framework should give you a nice Association between the two classes, Update the references as you would using POCOs and stay away from the ID values.
Something like:
newTeam.Profile.Teams.Remove(profileData); // separate from old Profile
profileData.Teams.Add(newTeam);
EDIT:
I made a little test, it is sufficient to set the reference to the Parent object:
newTeam.Profile = profileData;
I have a winforms application with two DataGridViews displaying a master-detail relationship from my Person and Address tables. Person table has a PersonID field that is auto-incrementing primary key. Address has a PersonID field that is the FK.
I fill my DataTables with DataAdapter and set Person.PersonID column's AutoIncrement=true and AutoIncrementStep=-1. I can insert records in the Person DataTable from the DataGridView. The PersonID column displays unique negative values for PersonID. I update the database by calling DataAdapter.Update(PersonTable) and the negative PersonIDs are converted to positive unique values automatically by SQL Server.
Here's the rub. The Address DataGridView show the address table which has a DataRelation to Person by PersonID. Inserted Person records have the temporary negative PersonID. I can now insert records into Address via DataGridView and Address.PersonID is set to the negative value from the DataRelation mapping. I call Adapter.Update(AddressTable) and the negative PersonIDs go into the Address table breaking the relationship.
How do you guys handle primary/foreign keys using DataTables and master-detail DataGridViews?
Thanks!
Steve
EDIT:
After more googling, I found that SqlDataAdapter.RowUpdated event gives me what I need. I create a new command to query the last id inserted by using ##IDENTITY. It works pretty well. The DataRelation updates the Address.PersonID field for me so it's required to Update the Person table first then update the Address table. All the new records insert properly with correct ids in place!
Adapter = new SqlDataAdapter(cmd);
Adapter.RowUpdated += (s, e) =>
{
if (e.StatementType != StatementType.Insert) return;
//set the id for the inserted record
SqlCommand c = e.Command.Connection.CreateCommand();
c.CommandText = "select ##IDENTITY id";
e.Row[0] = Convert.ToInt32( c.ExecuteScalar() );
};
Adapter.Fill(this);
SqlCommandBuilder sb = new SqlCommandBuilder(Adapter);
sb.GetDeleteCommand();
sb.GetUpdateCommand();
sb.GetInsertCommand();
this.Columns[0].AutoIncrement = true;
this.Columns[0].AutoIncrementSeed = -1;
this.Columns[0].AutoIncrementStep = -1;
You need to double click the relationship in the dataset designer, and select Cascade Updates. When your real SQL server generated PK values for your Person table are generated, it will automatically set the foreign key values in the address table as well.
You don't need to do any of that RowUpdated event stuff. Its built into the dataset functionality.
I had a similar problem, but my solution was a little different.
#Noel Kennedy: Your solution does not work with SQL Server 2005 CE, because it doesn't support multiple statements and the TableAdapter won't generate the refresh code needed to update the autoincrement columns in the parent table.
NOTE: You still need Cascade Updates in the relationship so the child tables get updated.
I also add a method in my TableAdapter, which is generic enough to just copy/paste in all your parent TableAdapters. The only thing that I change is the identity row type and index (if needed). I also add a query to the TableAdapter called GetIdentity(). You can add it to the TableAdapter in the dataset designer by adding a scalar query with sql="SELECT ##IDENTITY;"
Now the custom function is:
public int InsertAndRefresh(System.Data.DataTable dataTable)
{
int updated = 0;
System.Data.DataRow[] updatedRows = dataTable.Select("", "", System.Data.DataViewRowState.Added);
bool closed = (this.Connection.State == System.Data.ConnectionState.Closed);
if (closed)
this.Connection.Open();
foreach (System.Data.DataRow row in updatedRows)
{
updated+=this.Adapter.Update(new global::System.Data.DataRow[] { row });
decimal identity = (decimal)this.GetIdentity();
row[0] = System.Decimal.ToInt64(identity);
row.AcceptChanges();
}
if (closed)
this.Connection.Close();
return updated;
}
You want to call this on the parent first. Then do everything as usual (update parent and then children).
Cheers!