【发布时间】:2012-08-01 15:00:59
【问题描述】:
我正在学习 MVC,以更新我必须为我的雇主管理的一些旧的 ASP/ASP.Net Web 应用程序 - 我开始了解 ViewModels(很好尝试 - 因此这篇文章)。
在我的示例中帮助我学习 - 我有一家汽车经销商。每个 DealerShip 都有许多出租汽车。 Cars 被归类为 CarTypes - 每个 CarType 都可以有许多与之关联的 Cars。
CarType.cs
//
// Holds types of car - this has a one to many relationship with Car class
//
[Table("tType")]
public class CarType
{
[Key]
public int type_id { get; set; }
public int dealer_id { get; set; }
public string type_name { get; set; }
public string type_desc { get; set; }
public virtual ICollection<Car> Car { get; set; }
}
Car.cs
//
// Holds actual Cars
//
[Table("tCar")]
public class Car
{
[Key]
public int car_id { get; set; }
public int dealer_id { get; set; }
public int type_id { get; set; }
public int car_order { get; set; }
public string car_name { get; set; }
public virtual ICollection<Rental> Rentals { get; set; }
public virtual CarType CarType { get; set; }
}
Rental.cs
//
// This holds records of when cars are hired, and for which dealer, and for how long
//
[Table("tRental")]
public class Rental
{
[Key]
public int rental_id { get; set; }
public int dealer_id { get; set; }
public int car_id { get; set; }
public DateTime hire_from { get; set; }
public DateTime hire_to { get; set; }
public virtual Car Car { get; set; }
}
以上类映射到我的数据库。我已经读过要避免使用这样的模型,而应该使用 ViewModel。
在我的示例中,我想要做的是允许人们搜索特定的经销商、给定的日期和他们需要的雇用天数。
然后我想用以下内容填充视图模型:
- 需要日期车辆来自
- 需要汽车的天数
- DealerID(取自 URL - 例如。 http://mycars.com/search/avail/dealerGlasgow)
- 可用车型列表
- 每种车型的可用数量
为此,我想出了下面的 ViewModel:
SearchViewModel.cs
public class SearchViewModel
{
[Required]
public DateTime From { get; set; }
[Required]
public int DaysHire { get; set; }
public int dealer_id { get; set; }
public IQueryable<Car> Cars { get; set; }
}
现在我使用此视图模型在 ASP.Net MVC 中显示日历和天数搜索表单 - 因此我从表单上的隐藏字段(取自 URL)填充了 Dealer_id,并搜索数据库,使用我的控制器中的下面的 LINQ。
搜索首先会查找与该人要租用的日期重叠的任何租用 - 它将这些信息放入:
preBookedCars
然后它会通过dealer_id 搜索Cars - 并排除任何已经被雇用的:
freeCars
控制器代码为:
//
// POST: /Search/Avail/DealerName
[AllowAnonymous]
[HttpPost]
public ActionResult Avail(SearchViewModel model, string id)
{
if (ModelState.IsValid)
{
var dteFrom = model.From;
var dteTo = model.From.AddDays(model.Days);
// Search for any bookings for those dates, for the dealer specifed
var prebookedCars = db.Cars
.Where(car => car.Rentals.Any(rental =>
(model.dealer_id == rental.dealer_id && dteFrom >= rental.check_in && dteFrom < rental.check_out)
||
(model.dealer_id == rental.dealer_id && dteTo > rental.check_in && dteTo <= rental.check_out)
||
(model.dealer_id == rental.dealer_id && dteFrom <= rental.check_in && dteTo >= rental.check_out)
));
// Search for Cars, include the Car Type (so we can have description etc), and exclude any cars that have already been hired
var freeCars = db.Cars.Include("CarType")
.Where(car => car.dealer_id == model.dealer_id)
.Except(prebookedCars)
.OrderBy(o => o.car_order);
model.Cars = freeCars;
return View(model);
}
else
{
return View(model);
}
}
我有几个问题:
a) 我的用于 prebookedCars 的 Linq 是否有效?有没有办法我应该检查:
model.dealer_id == rental.dealer_id
...只有一次,而不是 3 次(例如,通过有 2 个 Where 子句)?
b) 查询,当我在 VS 中逐步浏览模型时 - 对于模型中的每辆汽车,我可以在 VS 中单击向下 - 即。 model.Cars.[Results View].Rentals - 并查看与该汽车相关的每个租赁 - 即使我只是想排除任何已经预订的汽车。如果我在视图中不使用该级别的详细信息,那么此列表在模型中是否重要?或者它存在的事实是否意味着我在我的模型/查询中增加了不必要的开销?
c) 我真的很想在我看来最终能够展示:
CarType (type_name) 和 Description (type_desc) - 在下拉框中,该类型的可用汽车数量。
我最终得到的是特定的个别汽车 - 而不是能够显示:
model.CarType.type_name 和 model.CarType.count
如何更改我的查询,以返回可用汽车类型的数量(或者我可以用上面的模型以某种方式做到这一点?)
我知道这很啰嗦 - 但我认为显示细节会有所帮助 - 如果有人能够帮助我的查询的任何部分,我将不胜感激。
谢谢,马克
【问题讨论】:
标签: asp.net asp.net-mvc asp.net-mvc-3 linq entity-framework