gpt4 book ai didi

c# - MVC 从远距离相关的多个域模型创建 View 模型

转载 作者:行者123 更新时间:2023-11-30 17:01:54 25 4
gpt4 key购买 nike

我一直在寻找一种方法来将 2 个远距离相关的域模型连接到一个 View 模型中,但没有成功。

我正在处理一个现有的应用程序,并被要求在传真日志搜索结果中添加一个字段。我的 Controller 正在返回一个 viewModel,我只想向它添加一个额外的字段。这听起来应该是一件容易的事。

背景信息:

这是原始的 View 模型:

public class VOEIFaxLogSearchListViewModel
{
public DateTime DateTimeAdded { get; set; }
public string Processor { get; set; }
public string FaxStatusCode { get; set; }
public string VendorOrderID { get; set; }
public string FromFaxNumber { get; set; }
}

我想向这个 View 模型添加一个额外的字段:

    public string CustomerName { get; set; }

应用程序的设计方式是调用存储过程以返回搜索结果的数据集。 (我不会搜索方法 (GetFaxLogSearchResult) 或其 SQL 调用,因为它不是必需的)

var resultFaxDS = vOEIDAO.GetFaxLogSearchResult(startDate,endDate,userName,faxType);

生成的 DataSet 然后被转换为 DataTable。

DataTable faxTable = resultFaxDS.Tables[0];

For 循环遍历每个结果记录并将它们放入名为 FaxModel 的域模型中。它使用 Automapper 映射到名为 FaxLogSearchListViewModel 的 viewModel。

for (int i=0; i<faxTable.Rows.Count;i++)
{
var row = faxTable.Rows[i];
var faxLogModel = vOEIDAO.DRToFaxModel(row);

faxViewModel.Add(Mapper.Map<FaxModel,FaxLogSearchListViewModel>(faxLogModel));
}
}

return faxViewModel;
}

这是我到目前为止为添加此结果字段所做的工作:

1) 将新属性添加到 View 模型。

2) 修改存储过程以返回搜索结果,以便返回数据集中的 CustomerName

困境:

将数据集的每一行添加到域模型 (DRToFaxModel) 的方法就是这样做的……它正在填充域模型 (FaxModel)。我要添加的字段不在域模型中。因此,如果字段不属于具体类,我不想将它添加到域模型。

下面是域模型和用于用搜索结果中的每一行填充它的方法:

public class FaxModel
{
public int FaxID { get; set; }
public int FaxStatusID { get; set; }
public string ToFaxNumber { get; set; }
public string FromFaxNumber { get; set; }
public DateTime DateTimeAdded { get; set; }
public string FaxStatusCode { get; set; }
public string Processor { get; set; }
public string VendorOrderID { get; set; }
}

public FaxModel DRToFaxModel(DataRow dr)
{
FaxModel voObj = new FaxModel();

voObj.FaxID = GetVOInt(dr["FaxID"]);
voObj.FaxStatusID = GetVOSmallInt(dr["FaxStatusID"]);
voObj.ToFaxNumber = GetVOStr(dr["ToFaxNumber"]);
voObj.FromFaxNumber = GetVOStr(dr["FromFaxNumber"]);
voObj.DateTimeAdded = GetVODateTime(dr["DateTimeAdded"]);
voObj.FaxStatusCode = GetVOStr(dr["FaxStatusCode"]);
voObj.Processor = GetVOStr(dr["Processor"]);
voObj.VendorOrderID = GetVOStr(dr["VendorOrderID"]);
//Cant add CustomerName to the model without modifying the FaxModel domain model.
//Shouldn't do that because it is a domain model.
//CustomerName is in the CustomerModel domain Model
// voObj.CustomerName = GetVOStr(dr["CustomerName"]);

return voObj;
}

因此,目前,我的添加了 CustomerName 属性的 ViewModel 返回时 CustomerName 为 null。

我的领域模型关系很远。在数据库中,FAX 表可以连接到 CUSTOMER 表,但只能通过 ORDER 表连接。 (FAX表有orderID字段,ORDER表有CustomerID字段)

所以我得出的问题是: 你如何使用 autoMapper 将传真域模型映射到客户域模型,因为这 2 个域没有任何公共(public)字段来建立关系而无需通过另一个表连接?

或者您可以使用自动映射器将 2 个以上的表映射到 1 个 viewModel 中吗?这是怎么做到的?

最佳答案

多么好的问题。首先,看到有人询问做某事的正确方法,而不仅仅是寻求快速修复,真是令人耳目一新。其次,提供的文档数量正是 SO 问题的编写方式。我希望我能给它超过 +1。

也就是说,由于您本质上是在问架构问题,因此没有任何具体答案,只有意见。

这是我的看法:

您声明存储过程的结果映射到域模型:

var resultFaxDS = vOEIDAO.GetFaxLogSearchResult(startDate,endDate,userName,faxType);

但是,您已将返回字段CustomerName 添加到您的存储过程,它不是域模型的一部分。我认为这是您问题的核心。

这里有一个选择:这个存储过程是否返回域模型?

现在,我的观点是它不再代表领域模型,因为新的领域,所以你不应该在将它映射到你的 View 模型之前尝试将它映射到领域模型。您需要创建一个新的数据类型来将此结果映射到,它表示您实际从存储过程中获得的内容,并将那个映射到您的 View 模型。

另一种选择是这个存储过程实际上代表了一个领域模型。如果是这种情况,您不应该向它添加不属于模型的新字段。相反,您需要分别获取 FaxModel 域对象和 CustomerModel 域对象,并从这两个对象组装您的 View 模型。

这是单一职责原则的一个例子,这意味着一个对象、函数、程序集,甚至是一个程序,都应该有一个目的。通过为您的 sproc 提供既是又不是领域模型的返回值,您赋予它的目的不止一个。最好要么决定它代表一个 FaxModel,并接受客户名称需要来自另一个来源,要么决定它返回其他东西,比如 CustomerFaxModel其中包含客户和传真信息,并按原样使用。

为了回答您的技术问题,除了源对象之外,AutoMapper 确实允许您将现有目标对象传递给 map 函数。您可以从对象 A 映射目标以获取一些字段,然后将已映射的目标与对象 B 的源一起第二次传递给 Map() 以映射其他字段。

永远,永远,不断地问这样的问题,你会做得很好。

关于c# - MVC 从远距离相关的多个域模型创建 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20529028/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com