【问题标题】:Setting up foreign key relationship in Entity Framework在实体框架中设置外键关系
【发布时间】:2018-10-25 18:47:07
【问题描述】:

我对 ASP.Net 和 Entity Framework Core 非常陌生,我正在开发一个简单的 Web 应用程序,用户可以在其中将饮料添加到购物车并结帐。还有一个用户的订单历史记录视图,这是我遇到问题的地方。每个订单都有一个订单行,该订单行是订单详细信息的列表。但是,当尝试从 orderdetail 中显示有关饮料的信息时,表示饮料为空。有人知道这是为什么吗?谢谢

订单模型如下图:

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

订单明细型号:

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

在 OrderRepository 中创建 Order 方法:

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

我还有一个 OrderHistory ViewModel:

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

}

控制器中的订单历史操作:

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

我的帐户视图:

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

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

【问题讨论】:

  • 调用CreateOrder 时似乎没有包含Drink 属性。
  • Order 模型不包含 Drink 的属性。 Drink 属性在订单详细信息中。当我在创建订单详细信息的位置上方放置一个断点时,我可以看到正在添加饮料。我只是之后无法检索它
  • 所以在请求 OrderDetail 时,你应该包含 Drink 导航属性。
  • @CodeNotFound 我为我的视图添加了代码,当我尝试 '@orderDetail.Drink.Name' 或 '@orderDetail.Drink.ImageUrl' 时,我得到一个 NullReferenceException 说饮料为空。跨度>
  • @AdnanNiloy 既然您提到我刚刚发现了问题。我在orderLines.AddRange() 查询中添加了.Include(od =&gt; od.Drink),现在它可以工作了

标签: c# asp.net entity-framework asp.net-core-mvc entity-framework-core


【解决方案1】:

我把orderLines.AddRange(_appDbContext.OrderDetails.Where(od =&gt; od.OrderId == order.OrderId));改成了orderLines.AddRange(_appDbContext.OrderDetails.Where(od =&gt; od.OrderId == order.OrderId).Include(od =&gt; od.Drink);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-20
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 2018-07-04
    • 2018-09-09
    • 2010-10-03
    • 2013-11-04
    相关资源
    最近更新 更多