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

时间:2015-03-27 14:33:53

标签: entity-framework wcf

我目前正在将我的实体从WCF发送到客户端,没有任何问题。问题在于,当我将一个给定实体发送回WCF(自客户端创建以来的引用完全相同)时,代码Context.Entry(entity).State将返回Detached

如果我在Context.ChangeTracker.Entries()进行检查,我会看到我的跟踪实体在那里,但它们似乎并不是"参考相关的"我从客户那里收到的。

有什么建议吗?我想通过WCF -> Client -> WCF一直使用相同的参考资料。

1 个答案:

答案 0 :(得分:2)

长话短说,你会发现断断续续是不可避免的。 EF正在创建一个不属于DataContract的代理类,因此补充跟踪数据会在[un]序列化过程中丢失。

然而,好消息是使用以下内容重新附加实体非常容易:

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

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

// 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