【问题标题】:Can WCF Code First DataServices return a NotMapped property?WCF Code First DataServices 可以返回 NotMapped 属性吗?
【发布时间】:2012-08-23 01:52:14
【问题描述】:

我将 WCF 数据服务用于返回 JSON 响应的 RESTful API。

考虑这个对象:

[Table("person")]
public class Person
{
    [Column("dob", TypeName = "datetime")]
    public DateTime DateOfBirth { get; set; }

    [NotMapped]
    public int Age
    {
        get { return CalculateAge(); }
        set { }
    }
}

WCF 不会像我期望的那样处理这个对象。我的服务请求完全忽略了 Person 对象序列化中的 Age 属性。

我一直在使用一种解决方法,将 Age 属性映射到一个虚拟数据库列,然后创建一个什么都不做的 setter。多么丑陋的黑客!有没有更好的方法让 DataService 返回未映射到数据库列的属性?

【问题讨论】:

    标签: wcf entity-framework-4 code-first dataservice


    【解决方案1】:

    经过大量研究,并且在 stackoverflow 上没有相反的证据,我将继续说答案是:不。使用 EntityFramework 4 映射实体的 WCF DataService 不能返回未映射的属性。

    我一直在使用的丑陋黑客是这个,它要求您在数据库中创建一个永远不会被读取的字段。

    [Table("person")]
    public class Person
    {
        [Column("dob", TypeName = "datetime")]
        public DateTime DateOfBirth { get; set; }
    
        [Column("dummy1", TypeName = "int")]
        public int Age
        {
            get { return CalculateAge(); }
            set { }
        }
    }
    

    【讨论】:

    • 我得出了同样的结论。实体框架does not expose 概念模型中的“NotMapped”属性,因此 WCF 数据服务永远不会看到它们。建议的解决方法是:1)在数据库中添加一个冗余列; 2)在数据库中添加一个虚拟列并在代码中计算其值; 3)计算客户端(所有客户端)的属性; 4) 使用Feed Customization,不幸的是只适用于ATOM,不支持JSON。
    【解决方案2】:

    这是我在这些情况下使用的,类似于 tyrongower 所说的:

    注意:这适用于 WCF 和 REST WCF 以及 JSON

    [DataContract]
    public class Submission
    {
        [NotMapped]
        [DataMember]
        public string Location
        {
            get { return ""; }
            set { }
        }
    }
    

    【讨论】:

      【解决方案3】:

      您可能需要使用 System.Runtime.Serialization 属性,因为这些是 WCF 将查看的内容。

      不确定您是否可以在数据合约中包含逻辑。

      [Table("person")]
      [DataContract]
      public class Person
      {
          [Column("dob", TypeName = "datetime")]
          [DataMember]
          public DateTime DateOfBirth { get; set; }
      
          [NotMapped]
          [DataMember]
          public int Age
          {
              get { return CalculateAge(); }
          }
      }
      

      编辑:

      可能需要私人二传手 (How do you configure a get-only property for a Silverlight-enabled WCF service)

      【讨论】:

      • 看起来很有希望,但可惜它不起作用。我的 JSON 对象在响应中仍然缺少 Age 属性。
      • 我也试过了,也没用。您分享的链接问题的不同之处在于它们的序列化对象未使用 EntityFramework 映射到数据库。
      【解决方案4】:

      我也遇到了这个问题并决定使用扩展方法。例如:

      public static class PersonExtensions
      {
          public static int GetAge(this Person person)
          {
              // your CalculateAge logic (simplified)
              return (DateTime.Now - person.DateOfBirth).TotalDays / 365;
          }
      }
      

      然后,在您的 DataServices 消费者中,您可以:

      person.GetAge()
      

      是的,它不如person.Age 好,但你也没有添加不必要的数据库列。

      更新:

      另一种选择是扩展服务引用中包含的 Person 类。您可以通过创建一个与服务引用 Person 类具有相同命名空间的部分 Person 类来做到这一点。例如:

      public partial class Person
      {
          public string int Age
          {
              get { return (DateTime.Now - this.DateOfBirth).TotalDays / 365; }
          }
      }
      

      那么 DataServices Person 模型将具有 Age 属性!

      【讨论】:

      • 非常酷的解决方法。我喜欢它们,但还没有尝试过。自从我上一篇文章以来,我已经重构了代码以不再使用 DataService,而只使用为我提供了更大灵活性的 vanilla WCF 服务。但也迫使我创建自己的带有分页、排序和查询的搜索方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-02
      • 1970-01-01
      • 2018-10-07
      • 1970-01-01
      • 2010-10-30
      • 1970-01-01
      相关资源
      最近更新 更多