【问题标题】:How to expose part of Entity as DataContract?如何将实体的一部分公开为 DataContract?
【发布时间】:2012-02-25 04:46:29
【问题描述】:

到目前为止,在使用 WCF 时,我一直将整个 EF 生成的实体或 POCO(通过修改 T4 模板以在 POCO 和属性上包含 DataContract 和 DataMember)公开为 DataContract。

现在,我遇到了一种情况,我无法公开整个事情,需要明确指定我的 DataContract 为实体的子集。

值得一提的是,我的一个实体如下所示:

我只想公开 Id、Name、CategoryId、Price。

其余字段(ActiveFromInactiveDateSupported)的插入/更新将根据 BR 决定,客户不知道,也不应该知道任何关于他们。

我尝试了以下方法,但每个方法似乎都有问题/不起作用:

  1. 使用 AutoMapper :我需要将源对象映射到 目标对象,这是一个单向映射,所以对于 演示目的我可以将Product 映射到ProductContract。但是对于添加/更新产品,它确实 不起作用,因为它无法进行双向映射

  2. 使用反射并为实体和创建元数据类 将[DataMember] 属性添加到元数据类的属性中,如下所示 (请注意,我没有包含不需要的字段):

    public class ProductMD : AssociatedMetadataTypeTypeDescriptionProvider
        {
            public ProductMD() :
                base(typeof(Product))
            {
            }
            [DataMember]
            public int Id{ get; set; }
    
            [DataMember]
            public string Name { get; set; }
    
            [DataMember]
            public int? CategoryID { get; set; }
    
            [DataMember]
            public decimal? Price { get; set; }
        }
    

    然后使用ProductMD 作为Product 的属性 部分类而不触及自动生成的实体(仅供参考:我有 更改了 POCO T4 模板生成器以包含 [DataContract] 在每个实体上):

    [MetadataType(typeof(ProductMD))]
    public partial class Product
    {  
    }
    

    但是在客户端,我没有 访问产品的任何DataMembers

现在我的问题是,获得我想做的事情的最佳方法是什么(将实体的子集公开为DataContract)?

【问题讨论】:

    标签: c# wcf entity-framework automapper datacontract


    【解决方案1】:

    我会选择选项 1 -> AutoMapper。

    它不起作用,因为它不能进行双向映射。

    您可以定义两种方式映射:

    Mapper.CreateMap<Product, ProductContract>();
    Mapper.CreateMap<ProductContract, Product>();
    

    显然,如果在您的 ProductContract 中进行映射时,您的属性少于域模型中的属性,则只会填充相应的属性。

    在进行逆映射进行更新时,您可以执行以下操作:

    ProductContract pc = ...
    Product productToUpdate = GetProduct(pc.Id);
    Mapper.Map<ProductContract, Product>(pc, product);
    // at this stage the product model will have the properties that
    // were present in the ProductContract being mapped from them and
    // the rest of the properties will stay unmodified, i.e. they will
    // have their initial values that were retrieved from the database.
    // Now we can update the product:
    UpdateProduct(product);
    

    【讨论】:

      【解决方案2】:

      首先,您应该永远不要将整个实体公开为数据合约,因为它是域对象,而不是数据传输对象。不只是在那种特殊情况下。绝不。现在,您在具有 DTO 的实体和没有 DTO 的实体之间制造了令人困惑的不一致。

      回到一个问题: AutoMapper 似乎还不错。您只需要定义 2 个映射。并且可能在映射回实体时 Ignore() 缺少属性。

      【讨论】:

        猜你喜欢
        • 2018-08-12
        • 1970-01-01
        • 1970-01-01
        • 2019-12-16
        • 1970-01-01
        • 1970-01-01
        • 2016-09-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多