Entity framework 使用代理将可跟踪EF实体传递给WCF服务
我目前正在将我的实体从WCF发送到客户端,没有问题。问题是,当我将一个给定的实体发送回WCF(自在客户端上创建该实体以来的同一引用)时,代码Entity framework 使用代理将可跟踪EF实体传递给WCF服务,entity-framework,wcf,Entity Framework,Wcf,我目前正在将我的实体从WCF发送到客户端,没有问题。问题是,当我将一个给定的实体发送回WCF(自在客户端上创建该实体以来的同一引用)时,代码Context.Entry(entity.State返回Detached 如果我对Context.ChangeTracker.Entries()进行检查,我会看到我跟踪的实体在那里,但它们似乎与我从客户那里收到的实体“引用相关” 有什么建议吗?我想在整个WCF->Client->WCF过程中一直使用相同的参考,长话短说,您将不可避免地遇到断开连接的情况。EF
Context.Entry(entity.State
返回Detached
如果我对Context.ChangeTracker.Entries()
进行检查,我会看到我跟踪的实体在那里,但它们似乎与我从客户那里收到的实体“引用相关”
有什么建议吗?我想在整个
WCF->Client->WCF
过程中一直使用相同的参考,长话短说,您将不可避免地遇到断开连接的情况。EF正在创建一个代理类,该类不属于您的DataContract
,因此补充跟踪数据在[un]序列化过程中丢失
但是,好消息是,使用以下内容可以很容易地重新附加实体:
[OperationContract]
void Update(Entity entity)
{
db.Set<Entity>().Attach(entity)
// carry on
}
然后绑定:
Mapper.CreateMap<UserEntity,UserDto>()
.ForMember(d => d.Id, m => m.MapFrom(s => s.Id))
.ForMember(d => d.UserName, m => m.MapFrom(s => s.UserName))
.ForSourceMember(s => d.Password, m => m.Ignore())
.ReverseMap()
.ForMember(d => d.Id, m => m.MapFrom(s => s.Id))
.ForMember(d => d.UserName, m => m.MapFrom(s => s.UserName))
.ForMember(d => d.Password, m => m.Ignore());
// Confirm we have everything configured correctly.
Mapper.AssertConfigurationIsValid();
Mapper.CreateMap()
.ForMember(d=>d.Id,m=>m.MapFrom(s=>s.Id))
.ForMember(d=>d.UserName,m=>m.MapFrom(s=>s.UserName))
.ForSourceMember(s=>d.Password,m=>m.Ignore())
.ReverseMap()
.ForMember(d=>d.Id,m=>m.MapFrom(s=>s.Id))
.ForMember(d=>d.UserName,m=>m.MapFrom(s=>s.UserName))
.ForMember(d=>d.Password,m=>m.Ignore());
//确认所有配置都正确。
assertConfigurationsValid();
然后,在实践中:
UserDto userDto = /* incoming model */
UserEntity user = Mapper.Map<UserEntity>(userDto);
db.Set<UserEntity>().Attach(user);
// carry on
UserDto UserDto=/*传入模型*/
UserEntity user=Mapper.Map(userDto);
db.Set().Attach(用户);
//继续
为什么不使用DTO?简单地重新连接又有什么错呢?这与使用MVC并将其发送到客户端并作为视图模型返回时遇到的问题相同。当命令db.Set().Attach(entity)
运行时,我收到:附加类型为“AtcManagerCommon.Models.Employee”的实体失败,因为同一类型的另一个实体已具有相同的主键值。如果图形中的任何实体具有冲突的键值,则在使用“Attach”方法或将实体状态设置为“Unchanged”或“Modified”时可能会发生这种情况。这可能是因为某些实体是新的,尚未收到数据库生成的键值可能为了简洁起见略过了几个部分,但这里有一篇关于附加的完整文章:问题是当我第一次创建服务并运行GetEntityByKey(int key)
时,上下文将返回的实体添加到它的ChangeTracker
。如果在使用Update(entity entity)
发回此实体时使用此键附加此实体,则会有重复的值。如果我将前者从ChangeTracker
中分离出来并附加新的,我相信与导航属性相关的一切都会变得一团糟。尽管如此,我还是要研究一下DTO。不过,我认为这并不能解决我当前的问题。我假设您正在为您的ServiceBehavior指定InstanceContextMode=InstanceContextMode.PerSession
您还可以抓取实体并根据跟踪器中已有的内容更新其值:db.Entry(trackedEntity).CurrentValues.SetValues(entity)
db.Entry(trackedEntity).CurrentValues.SetValues(entity)
是救了我的命!我建议您编辑您的答案,并在其上添加此重要部分。此外,我的InstanceContextMode
当前是“PerSession”(默认设置)。我在同一服务通道中使用客户端和服务器之间的两个事务。有什么问题吗?
UserDto userDto = /* incoming model */
UserEntity user = Mapper.Map<UserEntity>(userDto);
db.Set<UserEntity>().Attach(user);
// carry on