1

我有以下领域模型:

public class DaybookEnquiry : Entity
{
    public DateTime EnquiryDate { get; set; }
    [ForeignKey("EnquiryType")]
    public int DaybookEnquiryTypeId { get; set; }
    public string AccountNumber { get; set; }
    [ForeignKey("User")]
    public int UserId { get; set; }

    #region Navigation Properties

    public virtual User User { get; set; }
    public virtual DaybookEnquiryType EnquiryType { get; set; }
    public virtual ICollection<DaybookQuoteLine> QuoteLines { get; set; }

    #endregion
}

这是一个名为DomainModel. Entity只是我的域模型继承的基类,它包含一个Id字段。

然后,我的解决方案中有其他项目,称为ServiceInterfaceand ServiceModelServiceInterface包含我为我的应用程序提供的所有服务,并ServiceModel包含我的 DTO 和路线等。我正在尝试遵循此处列出的指南:物理项目结构

MyEnquiriesService包含一种使用存储库在我的数据库中创建新查询的方法:

public void Post(CreateEnquiry request)
{
    // Not sure what to do here..
    // _repository.Insert(request);
}

我的CreateEnquiry请求如下所示:

[Api("POST a single Enquiry for Daybook.")]
[Route("/enquiries", "POST")]
public class CreateEnquiry : IReturnVoid { }

如您所见,CreateEnquiry请求对象为空。我是否需要向它添加属性以匹配我的域模型,然后使用 AutoMapper 或类似的东西将字段映射到我的域模型并将其传递到我的存储库中?

我的存储库上的Insert方法如下所示:

public virtual void Insert(T entity)
{
    DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
    if (dbEntityEntry.State != EntityState.Detached)
    {
        dbEntityEntry.State = EntityState.Added;
    }
    else
    {
        DbSet.Add(entity);
    }

    DbContext.SaveChanges();
}
4

1 回答 1

4

是的。您的服务请求,在这种情况下,CreateEnquiry需要具有您需要的所有属性才能执行您想做的任何事情!

我已经看到了 Create vs Update 的两种不同模型:

  • 使用一个名为的请求对象,比如说,SetEnquiry它有一个可以为空的 id 字段。当为 null 并使用POSTHTTP 动词时,它会在内部创建一个新对象。当不为 null 并使用PATCHHTTP 动词时,它会在内部更新一个对象。您可以使用 ServiceStack 的实现AbstractValidator<T>来添加逻辑,例如如果 POST 则 id 字段需要为空;如果 PATCH 则 id 字段不能为 null。这将有助于确保您的数据始终如其所愿。
  • 创建两个请求对象——一个用于创建,一个用于更新。Create 甚至没有 id 字段,而 Update 有一个并且需要它。您可以使用上面使用的相同验证技术,除了单独应用于每个类,因此您不需要条件检查此动词是否执行此操作;如果那个动词那样做

如何映射到数据模型取决于您。您可以使用 AutoMapper 之类的东西,也可以使用 ServiceStack 的内置方法TranslateToPopulateWith方法。我个人采取了中间立场:我创建了自己的对象扩展方法,分别调用MapToMapFrom调用。我为什么这样做?因为然后我在自己的命名空间中控制这些扩展,并且当我需要进行特殊映射时(例如列名不匹配,或者一个对象比另一个对象更复杂,或者我只是想忽略一个特定列对象)我只是用显式类型重载and ,使其比泛型方法具有更高的特异性。TranslateToPopulateWithMapToMapFrom

所以回到你的问题。假设您使用的是内置TranslateTo的服务方法,可能如下所示:

public void Post(CreateEnquiry request)
{
    _repository.Insert(request.TranslateTo<Enquiry>());
}

还有一件事:我通常在创建和更新时返回对象本身。由于字段可以更改(例如自动计算字段),我喜欢将对象返回给调用者。这是偏好,与我给你的答案没有真正的关系。只是把它扔在那里!

于 2013-05-02T09:49:05.540 回答