Breeze.js混合DTO和实体

Joe*_*ley 4 entity-framework dto breeze

在Ward的文章" The Breeze Server:Have it your way "中:

典型的业务应用程序至少有200个域模型类型.我通过网络发送的数据形状的90%以上与我的业务模型中的实体形状相同.
...
当客户端实体的形状与服务器端业务实体的形状不一致时,我可能会针对该特定情况切换到DTO.

对于我们的应用而言,这可以直接敲击头部,但是为DTO 切换一些实体的最佳方法是什么?

例如,我们的用户实体包含不应向客户端公开的敏感属性.它还具有从其他系统中提取并返回到客户端的相关数据,理想情况下,这些数据应该是客户端User对象的额外属性.用户似乎是切换到DTO的理想候选者.

如果用户是一个孤立的实体,这可能会更容易,但问题是用户基本上在模型中的任何地方被引用.例如,几乎每个实体都有一个CreatedBy属性.

有没有办法在模型中的任何位置切换用户DTO的用户实体?对于模型中引用用户的所有其他实体,我们仍然需要能够在扩展其用户属性的情况下加载它们,在这些用户属性上查询它们,并通过对这些用户属性的更改来保存它们.

除了构建与实体模型95%相同的大型DTO模型之外,我不确定如何做到这一点,并且在它们之间有一些映射代码/框架.但是,正如沃德在这篇文章中所说的那样,"我不喜欢每种类型的DTO;这种过度杀伤可能会破坏生产力."

War*_*ard 5

你是一个很好的公司.像这样的问题正在堆积.我希望"尽快"提供更好的指导.

在短期内(假设您是.NET开发人员),您可以在DocCode示例中找到一些线索.搜索"ProductDto".DocCode没有显示你如何保存对它的更改,因此我必须暂时关闭它直到另一次.

您的方案实际上可能很容易解决.

第1步:使用自定义 DbContext

首先编写业务模型的子类DbContext.向您的子类添加一个覆盖,OnModelCreating并教它忽略User不应该属于模型的属性.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
   modelBuilder.Entity<User>().Ignore(u => u.whatever);
   ...
   base.OnModelCreating(modelBuilder);
}
Run Code Online (Sandbox Code Playgroud)

现在参考DbContext与客户沟通时得出的这个.

请注意,这涉及非常少量的代码并且易于维护.它不会干扰您对基础的使用,该基础DbContext保留了对所有属性的完全访问权限User.

步骤#2:配置JSON.NET以从序列化中排除这些属性

按照James Newton King的指导.看看特别是IContractResolver如果你不想装饰/污染您User与类[JsonIgnore]属性.James是JSON.NET的作者.

  • 确实!:-).简而言之:(1)从`EntityInfos`中删除DTO,(2)从Db中检索相应的业务模型实体(或者如果这是插入则创建这样的实体),(3)从DTO更新此副本,(4)添加此实体到`EntityInfos`(不要忘记更新的`OriginalValues`属性),(5)冲洗并重复所有这些DTO,(6)让它去......并且EF将保存它,(7)拦截"保存后"并将更新/插入的业务实体重新映射到"SaveResult"中的DTO表单,以便将DTO(而不是"真实"实体)发送回客户端.详细的恶魔我敢肯定. (3认同)
  • 保存更改是有趣的部分,因此"更好的指导"将非常有用! (2认同)