假设情景:
表3 我已经形成了一种多层次的关系:
Agent (AgentID (PK), AgentName)
AgentChannel (AgentID (PK), ChannelID (PK))
Channel (ChannelID (PK), ChannelName)
我不想在信使和海峡表格中添加/删除任何记录,而只是修改信使表格。
我正在使用EF4.1、POCO和自我跟踪实体。 所有涉及数据库的代码都包含在我称之为服务器侧码的WCF层,我只能控制客户密码中记录的添加/删除。
For example: I has one Agent record, with multiple Channel records. I able to link existing channel to agent in this way:
var channel = new Channel { ChannelID = 1 };
channel.MarkAsUnchanged();
agent.Channels.Add(channel);
// This will add new entry to AgentChannel table, but no change on Agent and Channel tables
此外,我还可以删除一条渠道与代理人的联系:
var tempChannels = agent.Channels.ToList();
var channelToDelete = tempChannels.FirstOrDefault(c => c.ChannelID == 3);
agent.Channels.Remove(channelToDelete);
// This will remove the entry in AgentChannel, but no change on Agent and Channel tables.
My problem:
If I removed a channel, and add back a new channel which has the same ChannelID with the previously removed channel into agent.Channels collection , I will get this error:
接受 改变不能继续,因为物体的关键价值与目标国Manager的另一物体相冲突。
缩略语:
//
// I not able to call ObjectContext here because it was reside in server side.
//
//
// This is client side code
//
var tempChannels = agent.Channels.ToList();
var channelToDelete = tempChannels.FirstOrDefault(c => c.ChannelID == 3);
// remove channel 3
agent.Channels.Remove(channelToDelete);
var channel = new Channel { ChannelID = 3 };
channel.MarkAsUnchanged();
// Add back channel 3
agent.Channels.Add(channel);
//
// This is server side code (WCF layer)
//
try
{
using (var ctx = new testEntities())
{
ctx.ApplyChanges("Agents", agent); // <-- ERROR happen here
ctx.SaveChanges();
}
}
catch (Exception)
{
throw;
}
然后,我发出特意例外信息:
System.InvalidOperationException was unhandled
Message=AcceptChanges cannot continue because the object s key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.
Source=System.Data.Entity
StackTrace:
at System.Data.Objects.ObjectStateManager.FixupKey(EntityEntry entry)
at System.Data.Objects.EntityEntry.AcceptChanges()
at System.Data.Objects.EntityEntry.ChangeObjectState(EntityState requestedState)
at System.Data.Objects.ObjectStateManager.ChangeObjectState(Object entity, EntityState entityState)
at TestManyToMany.SelfTrackingEntitiesContextExtensions.ChangeEntityStateBasedOnObjectState(ObjectContext context, IObjectWithChangeTracker entity) in F:MyFileDevelopmentTempTestManyToManyTestManyToManyModel1.Context.Extensions.cs:line 728
at TestManyToMany.SelfTrackingEntitiesContextExtensions.HandleEntity(ObjectContext context, EntityIndex entityIndex, RelationshipSet allRelationships, IObjectWithChangeTracker entity) in F:MyFileDevelopmentTempTestManyToManyTestManyToManyModel1.Context.Extensions.cs:line 596
at TestManyToMany.SelfTrackingEntitiesContextExtensions.ApplyChanges[TEntity](ObjectContext context, String entitySetName, TEntity entity) in F:MyFileDevelopmentTempTestManyToManyTestManyToManyModel1.Context.Extensions.cs:line 84
at TestManyToMany.Program.Main(String[] args) in F:MyFileDevelopmentTempTestManyToManyTestManyToManyProgram.cs:line 53
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
我希望我明确表示。 这是我现在面临的唯一问题,我没有想法。
许多感谢。
-
-
www.un.org/Depts/DGACM/index_spanish.htm 更新——答复
在根据Ladislav Mrnka的评论进行测试之后,我回答问题。
基本上,你需要重新加入以前撤走的同一实体,而没有其他实体,因为这样做会给你上述错误。
这里是客户方面的样本代码,服务器方面无需改动:
int channelId = 1;
var tempChannels = agent.Channels.ToList();
var channelToDelete = tempChannels.FirstOrDefault(c => c.ChannelID == channelId);
// remove channel 1
agent.Channels.Remove(channelToDelete);
//var channel = _allChannels.First(c => c.ChannelID == channelId);
//agent.Channels.Add(channel); <-- This line will give you ERROR because the channel entity is from _allChannels, but not from agent.Channels
// Add back channel 1
agent.Channels.Add(channelToDelete); // <-- This is CORRECT