使用代理将可跟踪的 EF 实体传递给 WCF 服务

Passing trackable EF Entity to WCF service, using proxies

我目前正在毫无问题地将我的实体从 WCF 发送到客户端。问题是,当我将一个给定实体发送回 WCF(自其在客户端创建以来的相同引用)时,代码 Context.Entry(entity).State returns Detached.

如果我对 Context.ChangeTracker.Entries() 进行检查,我发现我的跟踪实体在那里,但它们似乎与我从客户那里收到的实体不同 "reference related"。

有什么建议吗?我想在 WCF -> Client -> WCF.

中一直使用相同的参考

长话短说,您将无法避免断开连接。 EF 正在创建一个不属于您 DataContract 的代理 class,因此补充跟踪数据在 [un] 序列化过程中丢失。

不过,好消息是使用如下方式重新附加实体非常容易:

[OperationContract]
void Update(Entity entity)
{
    db.Set<Entity>().Attach(entity)
    // carry on
}

但是,我会考虑使用数据传输对象 (DTO) 并停止通过网络发送您的实际实体。您的数据可能很简单,但从长远来看 运行 它将节省您在版本控制、安全性等方面的时间。还有像 AutoMapper 这样的库可以使转换变得非常简单。例如

// Example EF model
[Table("Users")]
class UserEntity
{
    [Key]
    public Guid Id { get; set; }
    [Required]
    public String UserName { get; set; }
    [Required]
    public String Password { get; set; }
}

// Example DTO model
[DataContract]
class UserDto
{
    [DataMember]
    public Guid Id { get; set; }
    [DataMember]
    public String UserName { get; set; }
    // No need to send Password over the wire.
    // Let's keep things a bit more secure.
}

然后绑定:

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();

然后,在实践中:

UserDto userDto = /* incoming model */
UserEntity user = Mapper.Map<UserEntity>(userDto);
db.Set<UserEntity>().Attach(user);
// carry on