C# ASP.NET MVC中的模型关系
我最近开始评估ASP.NETMVC。虽然为仅具有基本属性的模型创建控制器和视图(如官方页面的初学者视频中所示)非常容易和快速,但我没有找到任何处理复杂类型引用的好方法。比如说,我有这些模型:C# ASP.NET MVC中的模型关系,c#,.net,asp.net-mvc,model,entity-relationship,C#,.net,Asp.net Mvc,Model,Entity Relationship,我最近开始评估ASP.NETMVC。虽然为仅具有基本属性的模型创建控制器和视图(如官方页面的初学者视频中所示)非常容易和快速,但我没有找到任何处理复杂类型引用的好方法。比如说,我有这些模型: public class Customer { public int Id { get; set; } public string Name { get; set; } public Address Address { get; set; } public I
public class Customer {
public int Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public IList<Order> Orders { get; set; }
}
public class Address {
public int Id { get; set; }
public string .....
.....
}
public class Order {
public int Id { get; set; }
public Customer Customer { get; set; }
public string OrderName { get; set; }
.....
}
公共类客户{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共广播地址{get;set;}
公共IList命令{get;set;}
}
公共类地址{
公共int Id{get;set;}
公共字符串。。。。。
.....
}
公共类秩序{
公共int Id{get;set;}
公共客户客户{get;set;}
公共字符串OrderName{get;set;}
.....
}
请注意,我在模型中没有外键(就像在示例视频中也使用的linqtosql的典型外键一样),而是一个对象引用
如何在asp.net mvc中处理此类引用?有人有关于这个问题的好提示或教程链接吗?可能包括复杂类型的自动绑定。您可以为此问题使用数据传输对象,也可以使用实体上的展开方法-EF中的包含方法- 基本属性没有什么不同。如果你不是这个意思,纠正我,我会再次帮助你 谢谢 DTO: NHibernate存储库:
public IList<OrderDTO> GetOrders()
{
return Session.Linq<Order>()
.Select(o => new OrderDTO {
Id = o.Id
CustomerId = o.Customer.Id
CustomerName = o.Customer.Name
...
}).ToList();
}
public IList GetOrders()
{
返回会话。Linq()
.选择(o=>neworderdto{
内径=外径
CustomerId=o.Customer.Id
CustomerName=o.Customer.Name
...
}).ToList();
}
视图:
扩展-包含-模型类型为“订单”:
<%= Model.Customer.Name %>
使用DTO-模型类型为“OrderDTO”:
<%= Model.CustomerName %>
编辑:
好的,首先您可能希望使用FormViewModel来创建/编辑操作。像这样,
控制器:
public ActionResult Edit(int id)
{
Order order = null; // OrderService.Get(id);
IList<Customer> customers = null; // CustomerService.GetAll();
OrderFormViewModel model = OrderFormViewModel.Create(order);
model.Customers = customers.Select(c => new SelectListItem {
Value = c.Id,
Text = c.Name
});
return View(model);
}
[HttpPost]
public ActionResult Edit(int customerId, Order order)
{
//customerId - selected from dropdown.
}
public class OrderFormViewModel
{
public static OrderFormViewModel Create(Order order)
{
return new OrderFormViewModel {
Order = order
};
}
public Order Order { get; internal set; }
public IEnumerable<SelectListItem> Customers { get; internal set; }
public int CustomerId { get; internal set; }
}
public ActionResult编辑(int-id)
{
Order-Order=null;//OrderService.Get(id);
IList customers=null;//CustomerService.GetAll();
OrderFormViewModel=OrderFormViewModel.Create(订单);
model.Customers=Customers.Select(c=>newselectListItem{
值=c.Id,
Text=c.名称
});
返回视图(模型);
}
[HttpPost]
公共操作结果编辑(int customerId,Order)
{
//customerId-从下拉列表中选择。
}
公共类OrderFormViewModel
{
公共静态OrderFormViewModel创建(订单)
{
返回新的OrderFormViewModel{
订单=订单
};
}
公共秩序{get;内部集合;}
公共IEnumerable客户{get;内部集合;}
public int CustomerId{get;internal set;}
}
视图:
o.CustomerId,Model.Customers)%>
我会将所有内容合并到我的视图模型中:
CustomerViewModel.Customer
CustomerViewModel.Address
CustomerViewModel.Orders // maybe an IEnumerable<Order>
CustomerViewMode.CurrentOrder
Hal我更喜欢尽可能地保持视图的“哑”,因此我喜欢创建自定义视图模型进行绑定 在控制器中,您可以将富域对象映射到视图模型的平坦模型。例如:
public class ChooseCustomerModel {
public Order Order { get; set; }
// Project Customer objects into this container, which is easy to bind to
public IDictionary<int, string> PotentialCustomers { get; set; }
}
public类选择客户模型{
公共秩序{get;set;}
//将客户对象投影到此容器中,该容器易于绑定
公共IDictionary潜在客户{get;set;}
}
如果您正在寻找关于这个主题的好材料,我推荐。谢谢您的回答。但是在没有DTO的情况下如何设置此引用(例如,在创建表单中)?有一个SelectList,但它只支持字符串values@Fabiano:一点也不,我现在刚刚编辑。使用
IEnumerable
进行下拉列表等-或者,如果这不是您想要的,请告诉我我将进行编辑。此外,如果您需要对对象进行大量自定义,您应该能够实现自己的模型绑定器并在那里进行处理。感谢链接。这是一篇有用的文章。
CustomerViewModel.Customer
CustomerViewModel.Address
CustomerViewModel.Orders // maybe an IEnumerable<Order>
CustomerViewMode.CurrentOrder
//.. begin form
<%=Html.HiddenFor(m=>m.Customer.Id)%>
<%=Html.TextboxFor(m=>m.Customer.FirstName)%>
<%=Html.TextBoxFor(m=>m.Address.City)%>
<%=Html.TextBoxFor(m=>m.ActiveOrder.OrderName%>
//.. submit ..
//.. end form ..
[HttpPost]
public ActionResult UpdateComplexObject(string id, CustomerViewModel customerViewModel) {
// if (!id.Equals(customerViewModel.Customer.Id) throw something
// just one of my own conventions to ensure that I am working on the correct active
// entity - string id is bound from the route rules.
ValidateModel(customerViewModel);
service.UpdateCustomer(customerViewModel.Customer);
serviceOrder.UpdateOrder(customerViewModel.ActiveOrder);
serviceAddress.UpdateAddress(customerViewModel.Address);
return RedirectToAction("DisplayComplexObject"); // or whatever
}
public class ChooseCustomerModel {
public Order Order { get; set; }
// Project Customer objects into this container, which is easy to bind to
public IDictionary<int, string> PotentialCustomers { get; set; }
}