我在项目中实现了EF 4。其中有客户和订单表。具有一个(客户)与多个(订单)的关系。

我正在为(CustomerViewModel和OrderViewModel)创建一个 View 模型,以便从我的域层传递到接口(interface)层(在本例中为MVC)。

现在的问题是“我需要同时引用两个 View 模型吗?例如,在customerviewmodel中具有IEnumerable<OrderViewModel>,在orderviewmodel中具有CustomerViewModel。如果是这样,我如何设计它(作为最佳实践),以便用正确的引用填充IEnumerable<OrderViewModel>CustomerViewModel

最佳答案

我将始终在考虑特定 View 的情况下驱动ViewModels的设计,而不是从域模型(=实体)的角度出发。 ViewModel的外观取决于您要显示的内容和要在 View 中修改的内容。

结果,您没有THE OrderViewModel和THE CustomerViewModel,因为您具有不同的 View ,这些 View 将显示或编辑订单或客户或其中的一部分。因此,您具有用于特定目的和 View 的ViewModel,因此可以多次使用不同的版本。

假设您有一个OrderEditView,此 View 将允许编辑订单信息并显示该订单的客户。您将拥有一个像这样的OrderEditViewModel:

public class OrderEditViewModel
{
    public int OrderId { get; set; }

    public DateTime? ShippingDate { get; set; }

    [StringLength(500)]
    public string Remark { get; set; }
    //...

    public OrderEditCustomerViewModel Customer { get; set; }
}

public class OrderEditCustomerViewModel
{
    [ReadOnly(true)]
    public string Name { get; set; }

    [ReadOnly(true)]
    public string City { get; set; }
    // ...
}

OrderEditCustomerViewModel不需要引用OrderEditViewModel

您可以像这样填充此ViewModel:
var orderEditViewModel = context.Orders
    .Where(o => o.OrderId == 5)
    .Select(o => new OrderEditViewModel
    {
        OrderId = o.OrderId,
        ShippingDate = o.ShippingDate,
        Remark = o.Remark,
        Customer = new OrderEditCustomerViewModel
        {
            Name = o.Customer.Name,
            City = o.Customer.City
        }
    })
    .SingleOrDefault();

另一方面,如果您有一个CustomerEditView,它可以编辑客户信息并在列表中显示客户的订单,则ViewModel可能是:
public class CustomerEditViewModel
{
    public int CustomerId { get; set; }

    [Required, StringLength(50)]
    public string Name { get; set; }

    [Required, StringLength(50)]
    public string City { get; set; }
    //...

    public IEnumerable<CustomerEditOrderViewModel> Orders { get; set; }
}

public class CustomerEditOrderViewModel
{
    [ReadOnly(true)]
    public DateTime? ShippingDate { get; set; }

    [ReadOnly(true)]
    public string Remark { get; set; }
    // ...
}

这里CustomerEditOrderViewModel不需要引用CustomerEditViewModel,您可以通过这种方式从数据库创建ViewModel,例如:
var customerEditViewModel = context.Customers
    .Where(c => c.CustomerId == 8)
    .Select(c => new CustomerEditViewModel
    {
        CustomerId = c.CustomerId,
        Name = c.Name,
        City = c.City,
        Orders = c.Orders.Select(o => new CustomerEditOrderViewModel
        {
            ShippingDate = o.ShippingDate,
            Remark = o.Remark
        })
    })
    .SingleOrDefault();
Customer(*)ViewModelOrder(*)ViewModel不同-关于必要的引用,属性和数据注释,这取决于使用它们的 View 。

考虑到这些注意事项,关于OrderViewModelCustomerViewModel之间的相互正确引用的问题就消失了,因为您通常不需要这种双向引用来查看。

10-07 12:51