是否可以在显示 model/viewmodel 上包含不包含导航 属性 的模型

is it possible to include a model that doesn't contain a navigation property on the displaying model/viewmodel

我有 2 个 类,我已经为它们创建了一个视图模型:

public class Sweet
{
    public int SweetID { get; set; }

    public int CategoryID { get; set; }
    public Category Category { get; set; }
    public string SweetName { get; set; }
    public bool Singular { get; set; }
    public string Description { get; set; }
    public decimal Price { get; set; }


    public virtual ICollection<Cart> Carts { get; set; }
}


public class Cart
{
    [Key]
    public int RecordID { get; set; }
    public string CartID { get; set; }
    public int SweetID { get; set; }
    public int PemixID { get; set; }
    public int Qty { get; set; }
    public System.DateTime DateCreated { get; set; }

    public Sweet Sweet { get; set; }
    public PreMix PreMix { get; set; }

}

视图模型:

public class SweetViewModel
{
    public IEnumerable<Sweet> Sweet { get; set; }
    public IEnumerable<Cart> Cart { get; set; }
}

我正在尝试显示所有糖果的列表,包括当前购物车中每种糖果的数量(当前购物车中可能不存在该糖果)。

我已经编写了我需要的数据的基本查询,但不确定如何以 MVC 方式执行此操作:

select Sweets.*, Qty
from Sweets
left join (select SweetID,  Qty from carts where CartID = '7125794e-38f4- 4ec3-b016-cd8393346669' ) t 
on Sweets.SweetID = t.SweetID

控制器:

public ActionResult SweetTestArea()
{
   var viewModel = new SweetViewModel
   {

       Sweet = db.Sweets.Include(s => s.Carts)    

   };

   return View(viewModel);
}

查看:

@model  WebApplication1.ViewModels.SweetViewModel

@foreach (var item in Model.Sweet)
{
    @Html.DisplayFor(modelItem => item.SweetName)

    //this doesn't work
    @Html.DisplayFor(modelItem => item.Cart.Qty)
}

通过查看您想要显示的视图 "SweetName" 和 "Qty"。

因此,为此你必须重新构建你的 "SweetViewModel" 就像

public class SweetViewModel
    {
        //From Sweet Model
        public int SweetID { get; set; }
        public int CategoryID { get; set; }
        public Category Category { get; set; }
        public string SweetName { get; set; }
        public bool Singular { get; set; }
        public string Description { get; set; }
        public decimal Price { get; set; }

        //From Cart Model
        public int Qty { get; set; }
    }

并且根据您的输出,您必须将视图设计为

@model IEnumerable<WebApplication1.ViewModels.SweetViewModel>

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>SweetTestArea</title>
</head>
<body>
    <p>
        @Html.ActionLink("Create New", "Create")
    </p>
    <table class="table">    
    @foreach (var item in Model) {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.SweetID)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CategoryID)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.SweetName)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Description)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Price)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Qty)
            </td>
        </tr>
    }

    </table>
</body>
</html>

你的控制器代码看起来像

 public ActionResult SweetTestArea()
        {
            List<SweetViewModel> viewModel = new List<SweetViewModel>();

            var q = (from s in db.Sweets
                     join c in db.Carts on s.SweetID equals c.SweetID
                     where c.CartID == "7125794e-38f4- 4ec3-b016-cd8393346669"
                     select new SweetViewModel
                     {
                         CategoryID = s.CategoryID,
                         Description = s.Description,
                         Price = s.Price,
                         Qty = c.Qty,
                         SweetID = s.SweetID,
                         SweetName = s.SweetName
                     });

            viewModel = q.ToList();

            return View(viewModel);
        }

如果您想要左连接,那么您的 linq 查询将是

var q = (from s in db.Sweets
                     join c in db.Carts on s.SweetID equals c.SweetID into j
                     from c in j.DefaultIfEmpty()
                     where c.CartID == "7125794e-38f4- 4ec3-b016-cd8393346669"
                     select new SweetViewModel
                     {
                         CategoryID = s.CategoryID,
                         Description = s.Description,
                         Price = s.Price,
                         Qty = c.Qty,
                         SweetID = s.SweetID,
                         SweetName = s.SweetName
                     });

我建议你不要使用左连接,因为你想在你的购物车中显示来自 Sweet 和 Cart 的两个模型的数据意味着购物车中至少有 1 件商品。

编辑:

根据您上次的评论,我了解到您希望每件商品都显示在您的购物车中,无论是否在您的购物车模型中

所以

1) 让我们先拿走您的购物车商品

List<SweetViewModel> cart = new List<SweetViewModel>();

            var q = (from s in db.Sweets
                     join c in db.Carts on s.SweetID equals c.SweetID into l
                     from c in l.DefaultIfEmpty()
                     where c.CartID == "7125794e-38f4- 4ec3-b016-cd8393346669"
                     select new SweetViewModel
                     {
                         CategoryID = s.CategoryID,
                         Description = s.Description,
                         Price = s.Price,
                         Qty = c.Qty,
                         SweetID = s.SweetID,
                         SweetName = s.SweetName
                     });


            cart = q.ToList();

2) 然后获取所有糖果并将它们投影到 SweetViewModel

List<SweetViewModel> allSweets = new List<SweetViewModel>();

            var w = (from s in db.Sweets
                     select new SweetViewModel
                     {
                         CategoryID = s.CategoryID,
                         Description = s.Description,
                         Price = s.Price,
                         Qty = 0,
                         SweetID = s.SweetID,
                         SweetName = s.SweetName
                     });

            allSweets = w.ToList();

3) 过滤掉购物车中的那些糖果 您将在下面的过滤列表中获得甜蜜的 ID

var filteredSweets = allSweets.Select(x => x.SweetID).Where(x => !cart.Select(y => y.SweetID).Contains(x)).ToList();

4) 将过滤后的糖果添加到视图模型中

List<SweetViewModel> viewModel = new List<SweetViewModel>();

            foreach (var i in filteredSweets)
                viewModel.Add(allSweets.Where(x => x.SweetID == i).Take(1).SingleOrDefault());

5) 然后将您的购物车商品添加到视图模型中

viewModel.AddRange(cart);

和return要查看的此视图模型。

您可以根据需要使用 order by 对购物车中的商品进行排序。