Melo Tang
Melo Tang

Reputation: 23

lambda expression Problems

My question is when I click actionlink,the view send specific ID to controller(ex. ProductID = 6), but my controller grab all data to me not specific ID data.

I think the problem is the lambda expression at controller, it will grab all data to me.

These are my Models:

    public class ShoppingCart
    {
        public List<ShoppingCartItemModel> items = new List<ShoppingCartItemModel>();

        public IEnumerable<ShoppingCartItemModel> Items 
        {
            get { return items; }
        }
    }


    public class ShoppingCartItemModel
    {
        public Product Product
        {
            get;
            set;
        }

        public int Quantity { get; set; }
    }

Controller :

        [HttpGet]
        public ActionResult EditFromCart(int ProductID)
        {

            ShoppingCart cart = GetCart();
            cart.items.Where(r => r.Product.ProductID == ProductID)
                      .Select(r => new  ShoppingCartItemModel
                                        {
                                            Product = r.Product,
                                            Quantity = r.Quantity
                                        });

            return View(cart);

            //return RedirectToAction("Index", "ShoppingCart");
        }


        private ShoppingCart GetCart()
        {
            ShoppingCart cart = (ShoppingCart)Session["Cart"];

            //如果現有購物車中已經沒有任何內容
            if (cart == null)
            {
                //產生新購物車物件
                cart = new ShoppingCart();

                //用session保存此購物車物件
                Session["Cart"] = cart;
            }

            //如果現有購物車中已經有內容,就傳回 view 顯示
            return cart;
        }

View

@model ShoppingCart

@{
    ViewBag.Title = "購物車內容";
}

<h2>Index</h2>

<table class="table">
    <thead>
        <tr>
            <th>
                Quantity
            </th>
            <th>
                Item
            </th>
            <th class="text-right">
                Price
            </th>
            <th class="text-right">
                Subtotal
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.items)
        {
            <tr>
                <td class="text-center">
                    @item.Quantity
                </td>
                <td class="text-center">
                    @item.Product.ProductName
                </td>
                <td class="text-center">
                    @item.Product.Price.ToString("c")
                </td>
                <td class="text-center">
                    @( (item.Quantity * item.Product.Price).ToString("c"))
                </td>
                <td>
                    @using (Html.BeginForm("RemoveFromCart", "ShoppingCart"))
                    {
                        @Html.Hidden("ProductId", item.Product.ProductID)
                        @*@Html.HiddenFor(x => x.ReturnUrl)*@
                        <input class="btn btn-warning" type="submit" value="Remove">
                    }
                </td>
                <td>
                    @using (Html.BeginForm("EditFromCart", "ShoppingCart", FormMethod.Get))
                    {
                        @Html.Hidden("ProductId", item.Product.ProductID)
                        <input class="btn btn-warning" type="submit" value="Edit">
                    }
                </td>

            </tr>
        }
    </tbody>

</table>

Upvotes: 1

Views: 60

Answers (3)

Jason Evans
Jason Evans

Reputation: 29186

The key issue is that this code doesn't return the result of the LINQ queries, because you have not assigned a variable to the result:

cart.items.Where(r => r.Product.ProductID == ProductID)
                      .Select(r => new  ShoppingCartItemModel
                                        {
                                            Product = r.Product,
                                            Quantity = r.Quantity
                                        });

I strongly suggest you create a viewmodel specifically to display the cart items.

public class CartItemsViewModel
{
    public List<ShoppingCartItemModel> Items { get; set; }
}

[HttpGet]
public ActionResult EditFromCart(int ProductID)
{

    ShoppingCart cart = GetCart();

    var viewModel = new CartItemsViewModel();

    viewModel.Items.AddRange(cart.items.Where(r => r.Product.ProductID == ProductID)
                .Select(r => new  ShoppingCartItemModel
                                {
                                    Product = r.Product,
                                    Quantity = r.Quantity
                                }));

    return View(viewModel);
}

In my example I use the .AddRange() method to take the results of the LINQ calls against the cart items and store them in the viewmodel's Items property.

Upvotes: 2

Bharat
Bharat

Reputation: 2464

You must have to assign filtered value to cart like this.

cart.item = cart.items.Where(r => r.Product.ProductID == ProductID)
                      .Select(r => new  ShoppingCartItemModel
                                        {
                                            Product = r.Product,
                                            Quantity = r.Quantity
                                        }).ToList();

use ToList(); or FirstOrDefault() as per your condition

Upvotes: 0

Andy Lamb
Andy Lamb

Reputation: 2304

You need to hold the return value from the linq query on cart.Items in a variable and pass that to the View method. At the moment, the result of your query is being lost and the whole cart passed to the View method.

Upvotes: 0

Related Questions