【问题标题】:EF Navigation Properties in WCF Data ContractsWCF 数据协定中的 EF 导航属性
【发布时间】:2015-07-12 09:27:54
【问题描述】:

我正在尝试学习一些使用 WCF 合同的最佳实践。我有一个POCO实体类,如下图:

public class Job : IOwnerEntity<int>, ILoggableEntity
{
    public int JobID { get; set; }
    public int JobtypeCodeID { get; set; }
    public string JobName { get; set; }
    public int CustomerID { get; set; }
    public int JobStatusID { get; set; }
    public DateTime CreationDate { get; set; }
    public DateTime ModifiedDate { get; set; }

    public virtual Customer Customer { get; set; }
    public virtual ICollection<JobUserAssignment> JobUsers { get; set; }

    public int OwnerEntityID
    {
        get
        {
            return JobID;
        }
        set
        {
            JobID = value;
        }
    }
}

现在,当我创建相应的数据合同时,是否建议在数据合同中包含导航属性(此处为 JobUserAssignment 和 Customer)..?详细来说,以下哪种合约是推荐的方式?

[ServiceContract]
interface IJobService
{
    Job GetJob(int id);//Gets job + job.Customer + job.JobUsers
}

[ServiceContract]
interface IJobService
{
    Job GetJob(int id);//Gets onlyjob 
    Customer GetCustome(int jobid);
    JobUserAssignment[] GetUsers(int jobid);
}

提前致谢,

普雷迪普

【问题讨论】:

    标签: entity-framework wcf


    【解决方案1】:

    一如既往:视情况而定

    如果您检索到Job,您是否总是(或几乎总是)还需要客户和该工作的分配?然后使用方法#1,它总是返回所有内容。

    如果您只是偶尔需要客户和任务(仅在 10%、20% 的情况下)并且如果检索该信息非常昂贵/效率低下,那么我会使用方法 #2 仅加载当真正需要时。

    如果您始终需要该信息,则首选在一次调用中获取所有内容 - 让您的用户在每次需要某些内容时调用三种方法来获取所有内容是没有意义的。

    但是,如果仅在极少数情况下需要额外的信息,那么每次检索 Job 时都没有必要进行所有工作 - 在这种情况下,由用户决定何时需要额外信息(或不需要)。

    【讨论】:

      【解决方案2】:

      将服务层与数据模型联系起来并不是一个好习惯。您遇到的问题是随着数据模型的发展(新列、验证等),您的服务将需要与服务的消费者重新同步。

      相反,分离数据模型并在 WCF 层公开一组不同的对象。

      以下示例已将您的版本修改为:

      • 代表数据库中表的类
      • 表示从 WCF 发送的数据的类

      以下是这些类的代码:

      // Data Layer ---------------------
      // In namespace Company.Data.Models
      
      public class Job : IOwnerEntity<int>, ILoggableEntity
      {
          public int JobID { get; set; }
          public int JobtypeCodeID { get; set; }
          public string JobName { get; set; }
      
          /* ... others here .... */
      }
      
      // -----------------------------------
      
      // Services Layer --------------------    
      // In namespace Company.Services.Contracts
      public interface IJobService 
      {
         Company.Services.Contracts.Job GetJobBy(int id);
      }
      
      // In namespace Company.Services.Contracts
      [DataContract]
      public class Job
      {
         [DataMember]
         public int ID { get; set; }
      
         [DataMember]
         public string Name { get; set; }
      }
      

      从这里,您可以使用Company.Services.Contracts 命名空间交换消息。原因是,如果您的数据库有额外的表列(比如新的JobCategory),那么任何消费者都不会受到影响。

      // In namespace Company.Services.Impl
      
      using Company.Data.Models;
      using Company.Services.Contracts;
      
      public class WcfJobService : IJobService
      {
          public Company.Services.Contracts.Job GetJobBy(int id)
          {
              EFDataContext dc = new EFDataContext();
              Company.Data.Models.Job dc = dc.Jobs.FirstOrDefault(x=> s.JobID = id);
      
              if(dc == null) { return null; }
      
              return new Company.Services.Contracts.Job { ID = dc.JobID, Name = dc.JobName };
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-12
        • 2017-12-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多