【问题标题】:Using ViewModels and Linq in ASP.Net MVC 4在 ASP.Net MVC 4 中使用 ViewModel 和 Linq
【发布时间】: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。

在我的示例中,我想要做的是允许人们搜索特定的经销商、给定的日期和他们需要的雇用天数。

然后我想用以下内容填充视图模型:

  1. 需要日期车辆来自
  2. 需要汽车的天数
  3. DealerID(取自 URL - 例如。 http://mycars.com/search/avail/dealerGlasgow)
  4. 可用车型列表
  5. 每种车型的可用数量

为此,我想出了下面的 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


    【解决方案1】:

    a) 我的用于 prebookedCars 的 Linq 是否有效?有没有办法我应该 检查:

    model.dealer_id == rent.dealer_id ...只有一次,而不是 3 次 (例如,通过有 2 个 Where 子句)?

    您可以更改您的声明以首先测试 model.dealer_id:

    db.Cars.Where(car => car.Rentals.Any(rental =>
                        (model.dealer_id == rental.dealer_id) && (
                        (dteFrom >= rental.check_in && dteFrom < rental.check_out)
                        ||
                        (dteTo > rental.check_in && dteTo <= rental.check_out)
                        ||
                        (dteFrom <= rental.check_in && dteTo >= rental.check_out))
                    ));
    

    关于 B:有几件事可能是错误的。您是否首先为此使用代码?如果是这样,您可能需要实现 Equals 函数,或者它可能是一个转换 linq 的东西。 This article 可能相关

    关于 C:我不确定我是否理解您的问题 - 但我认为您想要计算任何给定车型的可用汽车并显示它?如果是这样,由于您在遍历汽车类型列表时已经有可用汽车的枚举(假设 b 有效),您可以从之前的查询中获得可用汽车的数量:

     foreach (var cartype in db.CarTypes)
                {
                    var numberAvailable = freeCars.Where(fc => fc.CarType == cartype);
                }
    

    这是一种伪代码,因为循环应该在您的视图中,并且可能会做许多其他事情,但我希望您明白这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 2019-09-27
      • 1970-01-01
      相关资源
      最近更新 更多