I have a checked listbox in a Windows Forms app that allows the user to assign one or more security groups to a selected user.
Using WCF Data Services, I am able to populate the box without a problem. However, as the user changes selections in the box and tries to save those changes, I run into issues.
Here is the code, with comments to explain my logic.
private void ProcessSecurityGroupSelection_Original()
{
//Get a reference to the selected user, including the associated SecurityGroups.
var user = _ctx.Users
.AddQueryOption("$filter", "UserID eq " + ((DataService.User)lstUsers.SelectedItem).UserID)
.AddQueryOption("$expand", "SecurityGroups")
.First();
//Remove all the SecurityGroups so we can replace them.
user.SecurityGroups.Clear();
foreach (var selectedGroup in lstSecurityGroups.CheckedItems)
{
//Loop through the selected SecurityGroups, linking and adding each SecurityGroup to the User object.
var securityGroup = (from sg in _ctx.SecurityGroups
where sg.SecurityGroupID == ((DataService.SecurityGroup)selectedGroup).SecurityGroupID
select sg).First();
_ctx.AddLink(user, "SecurityGroups", securityGroup);
user.SecurityGroups.Add(securityGroup);
}
_ctx.UpdateObject(user);
_ctx.SaveChanges();
}
When the code hits the AddLink method for a SecurityGroup that had previously been selected, I get an error stating "The context is already tracking the relationship." It doesn't appear that the Clear() method removes any links in the context.
How do I go about removing the existing links, or am I approaching this all wrong?
One way to remove the links is to add an event like the following:
private void lstSecurityGroups_ItemCheck(object sender, ItemCheckEventArgs e)
{
if (e.NewValue == CheckState.Unchecked)
{
_ctx.DetachLink(user, "SecurityGroups", securityGroup);
}
else if (e.NewValue == CheckState.Checked)
{
_ctx.AddLink(user, "SecurityGroups", securityGroup);
}
}
Note that DeleteLink
will mark the entity for deletion also, which will cause an error if called multiple times. If you just want to remove the link, use DetachLink
.