我在 Windows 窗体应用程序中有一个选中的列表框,允许用户将一个或多个安全组分配给选定的用户。
使用 WCF 数据服务,我可以毫无问题地填充框。但是,当用户更改框中的选择并尝试保存这些更改时,我遇到了问题。
这是代码,注释解释了我的逻辑。
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();
}
当代码点击先前选择的 SecurityGroup 的 AddLink 方法时,我收到一条错误消息,指出“上下文已经在跟踪关系”。 Clear() 方法似乎没有删除上下文中的任何链接。
我该如何删除现有链接,还是我的处理方式全错了?
请您参考如下方法:
我在一个 silverlight 项目中遇到了同样的问题。我采用了对我有用的解决方案并将其应用于您的 User/SecurityGroup 模型。
将以下内容添加到您的用户类:
public User()
{
this.SecurityGroups.CollectionChanged += (sender, e) =>
{
if (e.Action == Add)
{
foreach (SecurityGroup AddedGroup in e.NewItems)
AddSecurityGroup(AddedGroup);
}
if (e.Action == Remove)
{
foreach (SecurityGroup RemovedGroup in e.OldItems)
RemoveSecurityGroup(RemovedGroup);
}
};
..... rest of constructor
}
public void AddSecurityGroup(SecurityGroup secGroup)
{
LinkDescriptor descriptr = _ctx.GetLinkDescriptor(this, "SecurityGroups", secGroup);
if (descriptr == null)
_ctx.AddLink(this, "SecurityGroups", secGroup);
else if (descriptr.State == EntityStates.Deleted)
_ctx.DetachLink(this, "SecurityGroups", secGroup);
}
public void RemoveSecurityGroup (SecurityGroup secGroup)
{
LinkDescriptor descriptr = _ctx.GetLinkDescriptor(this, "SecurityGroups", secGroup);
if (descriptr == null)
{
_ctx.AttachLink(this, "SecurityGroups", secGroup);
_ctx.DeleteLink(this, "SecurityGroups", secGroup);
}
else if (descriptr.State == EntityStates.Added)
_ctx.DetachLink(this, "SecurityGroups", secGroup);
else
_ctx.DeleteLink(this, "SecurityGroups", secGroup);
}
现在删除行:
_ctx.AddLink(user, "SecurityGroups", securityGroup);
来自您上面的代码。
