简体   繁体   中英

Setting up foreign key relationship in Entity Framework

I'm very new to ASP.Net and Entity Framework Core and I'm working on a simple web app where a user can add drinks to a cart and checkout. There is also a view with the order history of a user which is where I run into a problem. Each order has an order line which is a list of order details. However, when trying to display the information about the drink from the orderdetail, it's saying that the drink null. Does anybody know why this is? Thank you

The order model is shown below:

public class Order
{
    [BindNever]
    public int OrderId { get; set; }

    public string UserId { get; set; }

    public virtual List<OrderDetail> OrderLines { get; set; }

    [Required(ErrorMessage = "Please enter your first name")]
    [Display(Name = "First name")]
    [StringLength(50)]
    public string FirstName { get; set; }

    [Required(ErrorMessage = "Please enter your last name")]
    [Display(Name = "Last name")]
    [StringLength(50)]
    public string LastName { get; set; }

    [Required(ErrorMessage = "Please enter your address")]
    [StringLength(100)]
    [Display(Name = "Address Line 1")]
    public string AddressLine1 { get; set; }

    [Display(Name = "Address Line 2")]
    public string AddressLine2 { get; set; }

    [Required(ErrorMessage = "Please enter your zip code")]
    [Display(Name = "Zip code")]
    [StringLength(10, MinimumLength = 4)]
    public string ZipCode { get; set; }


    [Required(ErrorMessage = "Please enter your City")]
    [StringLength(50)]
    public string City { get; set; }

    [Required(ErrorMessage = "Please enter your State")]
    [StringLength(10)]
    public string State { get; set; }

    [Required(ErrorMessage = "Please enter your country")]
    [StringLength(50)]
    public string Country { get; set; }

    [Required(ErrorMessage = "Please enter your phone number")]
    [StringLength(25)]
    [DataType(DataType.PhoneNumber)]
    [Display(Name = "Phone number")]
    public string PhoneNumber { get; set; }

    [Required]
    [StringLength(50)]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    [BindNever]
    [ScaffoldColumn(false)]
    public decimal OrderTotal { get; set; }

    [BindNever]
    [ScaffoldColumn(false)]
    public DateTime DatePlaced { get; set; }
}

Order Detail Model:

public class OrderDetail
{
    public int OrderDetailId { get; set; }

    public int OrderId { get; set; }

    public int DrinkId { get; set; }

    public string DrinkName { get; set; }

    public int Amount { get; set; }

    public decimal Price { get; set; }

    public Drink Drink { get; set; }

    public Order Order { get; set; }
}

Create Order method in OrderRepository:

    public void CreateOrder(Order order, string userId)
    {
        order.UserId = userId;

        order.DatePlaced = DateTime.Now;
        _appDbContext.Orders.Add(order);

        var shoppingCartItems = _shoppingCart.ShoppingCartItems;

        foreach (var item in shoppingCartItems)
        {
            var orderDetail = new OrderDetail()
            {
                Drink = item.Drink,
                Amount = item.Amount,
                DrinkId = item.Drink.DrinkId,
                DrinkName = item.Drink.Name,
                OrderId = order.OrderId,
                Price = item.Drink.Price
            };

            order.OrderTotal += item.Drink.Price*item.Amount;

            _appDbContext.OrderDetails.Add(orderDetail);
        }


        _appDbContext.SaveChanges();
    }

I also have an OrderHistory ViewModel:

public class OrderHistoryViewModel
{
    public List<Order> OrderHistory { get; set; }
    public List<OrderDetail> OrderLines { get; set; }

}

OrderHistory Action in controller:

public async Task<ActionResult> MyAccount(OrderHistoryViewModel orderHistoryViewModel)
    {
        var user = await GetCurrentUserAsync();

        orderHistoryViewModel = new OrderHistoryViewModel
        {
            OrderHistory = _orderRepository.GetOrdersByCustomerId(user?.Id).ToList(),
            OrderLines = _orderRepository.GetOrderLines(_orderRepository.GetOrdersByCustomerId(user?.Id)).ToList()
        };

        return View(orderHistoryViewModel);
    }

My Account View:

@model orderHistoryViewModel

        @foreach (var order in @Model.OrderHistory)
    {
        @foreach (var orderDetail in order.OrderLines)
        {

            decimal subtotal = orderDetail.Price * orderDetail.Amount;

                <div class="panel-body">
                    <div class="row">
                        <div class="col-md-3"><img src=@orderDetail.Drink.ImageUrl class="media-object thumbnail-image-xs"></div>
                        <div class="col-md-9">
                            <div class="row">
                                <div class="col-lg-12">
                                    <h4><span><strong>@orderDetail.Drink.Name</strong></span></h4>
                                </div>
                                <div class="col-md-12">
                                    <span style="font-weight:600">Quantity: </span> @orderDetail.Amount
                                </div>
                                <div class="col-md-12">
                                    <span style="font-weight:600">Price: </span> @subtotal

                                </div>
                                <div class="col-md-12">
                                    <span style="font-weight:600">Date Placed: </span> @order.DatePlaced.ToShortDateString()
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
        }
    }

Implementations of OrdersByCustomerId and GetOrderLines:

        public IEnumerable<Order> OrdersByCustomerId(string id)=> _appDbContext.Orders.Where(o => o.UserId == id).OrderByDescending(d => d.DatePlaced);

    public IEnumerable<OrderDetail> GetOrderLines(IEnumerable<Order> orderHistory)
    {
        List<OrderDetail> orderLines = new List<OrderDetail>();
        foreach (var order in orderHistory)
        {
            orderLines.AddRange(_appDbContext.OrderDetails.Where(od => od.OrderId == order.OrderId));
        }

        return orderLines;
    }

I changed orderLines.AddRange(_appDbContext.OrderDetails.Where(od => od.OrderId == order.OrderId)); to orderLines.AddRange(_appDbContext.OrderDetails.Where(od => od.OrderId == order.OrderId).Include(od => od.Drink);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM