如何从存储过程结果实体框架中创建列表

时间:2018-12-18 20:38:43

标签: c# asp.net-mvc stored-procedures

我正在使用ASP.NET MVC和EF创建车辆预订应用程序,如果需要,用户可以在其中将多个车辆保留一个日期时间。我创建了一个存储过程,以防止车辆重复预订,但是在弄清楚如何将结果添加到列表中时遇到了麻烦。

示例:我想在2018年12月18日从12:00到13:00保留Vehicle#1和Vehicle#2 ....存储的过程转到db,以查找从中已保留Vehicle#1 12:00至13:00,但不保留Vehicle#2。由于foreach正在运行,alreadyReservedVehicle返回了.Count() = 0的结果,因为它看到了最后的结果,即没有保留Vehicle#2。应该显示一条错误消息,说明不允许重复预订,因为Vehicle#1已被预订,但未计入该预订。

是否有一种方法可以收集两个结果并告知应用程序,因为这2辆车中有一辆是保留的,所以都不能保留这辆车?

public ActionResult Create([Bind(Include = "ID,StartDate,EndDate,RequestorID,Destination,PurposeOfTrip,TransportStudentsFG,LastChangedBy,LastChangedDate,VehicleList,ThemeColor")] Reservations reservation)
{
    if (ModelState.IsValid)
    {
        var selectedVehicles = reservation.VehicleList.Where(x => x.IsChecked == true).ToList();
        List<usp_PreventDoubleBooking_Result> alreadyReservedVehicle = null;

        // get each vehicle that was selected to be reserved then check db to make sure it is available
        foreach (var selectedVehicle in selectedVehicles) 
        {             
            using (VehicleReservationEntities db = new VehicleReservationEntities())
            {
                alreadyReservedVehicle = db.usp_PreventDoubleBooking(selectedVehicle.ID, reservation.StartDate, reservation.EndDate).ToList();                             
            }
        }

        if (alreadyReservedVehicle.Count() == 0) // create a new reservation if the vehicle is available at the selected date and time
        {
            db.Reservations.Add(reservation);
            reservation.LastChangedDate = DateTime.Now;
            db.SaveChanges();
        }
        else
        {
            //return error message on page if vehicle is already reserved
            TempData["Error"] = "Double booking of vehicles is not allowed. Please choose another vehicle/time. Check the availability timeline before reserving to ensure there are no errors. Thank you.";
            return RedirectToAction("Create");
        }
    }
}

以上是我到目前为止所拥有的,并且我知道我已经接近了,因为假设用户仅尝试预订一辆已经预订的车辆,那么我所拥有的将起作用。当他们试图为多辆车创建预订时,代码仅计算列表中的最后一辆车,并以此作为确定是否保存预订的结果。

我曾考虑过将条件语句移到foreach中,但是我不希望为选择的每辆车都保存预订...这没有任何意义,因为只能保存1个预订,它只有多个可以关联的载具。

以下是查找预留车辆的存储过程:

SELECT 
    v.ID, r.StartDate, r.EndDate 
FROM 
    dbo.Reservations r
JOIN 
    dbo.ReservationToVehicle rtv ON r.id = rtv.ReservationID
JOIN 
    dbo.Vehicles v ON v.ID = rtv.VehicleID
WHERE
    (v.ID = @VehicleID)
    AND (r.StartDate <= @NewEndDate) 
    AND (r.EndDate >= @NewStartDate)

那么如何获取alreadyReservedVehicle List并将每个结果添加到列表中,以便确定List是否实际上具有Count为0? >

更新:

这是存储过程的模型

public partial class usp_PreventDoubleBooking_Result
{
    public int ID { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
}

2 个答案:

答案 0 :(得分:2)

public ActionResult Create(/*Bind attribute omitted*/ Reservations reservation)
{
    if (ModelState.IsValid)
    {
        // Is 'IsChecked' nullable? If not, "== true" is redundant.
        var selectedVehicles = reservation.VehicleList.Where(x => x.IsChecked == true).ToList();

        // get each vehicle that was selected to be reserved then check db to make sure it is available
        using (VehicleReservationEntities db = new VehicleReservationEntities())
        {
            foreach (var selectedVehicle in selectedVehicles)
            {
                // 'alreadyReservedVehicle' can be declared here because you don't need to let it
                // out of its cage, I mean the loop.
                List<usp_PreventDoubleBooking_Result> alreadyReservedVehicle =
                    db.usp_PreventDoubleBooking(selectedVehicle.ID, reservation.StartDate, reservation.EndDate).ToList();

                if (alreadyReservedVehicle.Count() > 0)
                {
                    //return error message on page if vehicle is already reserved
                    TempData["Error"] = "Double booking of vehicles is not allowed. Please choose another vehicle/time. Check the availability timeline before reserving to ensure there are no errors. Thank you.";
                    return RedirectToAction("Create");
                }
            }
        }

        // create a new reservation if the vehicle is available at the selected date and time
        db.Reservations.Add(reservation);
        reservation.LastChangedDate = DateTime.Now;
        db.SaveChanges();
    }
}

答案 1 :(得分:0)

您可以执行以下操作:

var preventDoubleBookingList= await context.Database.SqlQuery<usp_PreventDoubleBooking>("sproc_name", prams_here).ToListAsync();

您将必须创建一个与存储过程匹配的模型。