在ASP.Net使用的ViewModels和LINQ MVC 4(Using ViewModels

2019-10-17 03:12发布

我正在学习MVC,以更新一些旧的ASP / ASP.Net Web应用程序我来管理我的雇主 - 和我开始让我的头周围的ViewModels(以及尝试 - 因此后)。

在我的例子,以帮助我学习 - 我有一个汽车经销店。 每家经销商都有一定数量的汽车,他们出租。 该汽车被列为CarTypes - 和每个CarType可以具有多个与之相关联的汽车。

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; }


}

上述类映射到我的数据库。 我读过,使用这样的模式是要避免的,而是你应该使用一个视图模型。

我想在我的例子做的,是让人们搜索特定的经销商,与给定日期和天数聘请他们需要。

那么我想填充以下视图模型:

  1. 日期租车须
  2. 需要租车天数
  3. 该DealerID(这是从URL拍摄-如。 http://mycars.com/search/avail/dealerGlasgow )
  4. 可用的汽车类型的列表。
  5. 提供各车种的数

要做到这一点,我想出了下面的视图模型:

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天搜索表单日历和数量 - 所以我从填充隐藏字段的dealer_id形式(从网址获取),并搜索数据库,使用下面的LINQ在我的控制器。

搜索首先寻找重叠的人正在寻求聘用日期的任何租金 - 它把这些信息为:

preBookedCars

然后,它由dealer_id搜索汽车 - 和排除任何已经聘请了:

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);
        }


    }

我有几个问题:

一)是我的LINQ的prebookedCars效率? 有没有一种方法,我应该检查:

model.dealer_id == rental.dealer_id

......只有一次,而不是3倍(例如,通过具有2 Where子句为例)?

b)在查询时,当我踩着通过VS模型 - 对模型中的每个车,我可以在VS点击下 - 即。 model.Cars结果查看] .Rentals - 看到与汽车相关的所有服务 - 尽管我想突出部分要排除的已排任何汽车。 如果我不使用的详细程度在我看来,这很重要,这个名单是在模型中? 或一个事实,即它的存在,这是否意味着我增加不必要的开销,我的模型/查询?

三)我真的想结束了,在我看来,能够显示:

CarType(TYPE_NAME)和描述(type_desc) - 在一个下拉框,可用该类型的汽车数量。

我已经结束了是特定的个人汽车 - 而不是能够显示:

model.CarType.type_name和model.CarType.count

我应该如何改变我的查询,返回车上类型的可用数量(或者我可以与模型我上面做不知何故?)

我知道这是很长篇大论 - 但我想展示,将有助于细节 - 如果有人能够帮助我查询的任何部分,我将不胜感激。

谢谢,马克

Answer 1:

一)是我的LINQ的prebookedCars效率? 有没有一种方法,我应该检查:

model.dealer_id == rental.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的事情。 这篇文章可能与

关于C:我真的不知道我理解你的问题 - 但我认为你想计算的可用汽车对于任何给定的汽车类型和显示呢? 如果是这样,因为你已经拥有汽车(假设B工作)为您通过汽车类型的列表进行迭代,你可以从以前的查询获取可用的汽车数量的枚举:

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

这是一种伪代码回路应该在你的看法,并很可能会做一些其他的事情,但我希望你的想法。



文章来源: Using ViewModels and Linq in ASP.Net MVC 4