【问题标题】:Is it possible to combine 2 view models, each populated with 2 different LINQ queries and return to 1 view?是否可以组合 2 个视图模型,每个模型填充 2 个不同的 LINQ 查询并返回到 1 个视图?
【发布时间】:2018-08-17 18:38:54
【问题描述】:

我正在尝试在 1 个视图中显示 2 组数据:

第一个 LINQ:

var result = from add in db.Addresses
                     join u in db.Users on add.UserID equals u.Id
                     where CurrUser == add.UserID
                     select new AddressViewModel
                     {
                        FirstAddressLine = add.FirstAddressLine,
                        SecondAddressLine = add.SecondAddressLine,
                        Town = add.Town,
                        PostCode = add.PostCode,
                        Distance = addDis
                     };

第二个 LINQ:

var result = from c in db.Carts
                     join s in db.Sweets on c.SweetID equals s.SweetID
                     where c.CartID == cartId
                     select new ShoppingCartViewModel
                     {
                         SweetName = s.SweetName,
                         Qty = c.Qty,
                         Price = s.Price,
                         SweetTotal = (s.Price * c.Qty),
                         Singular = s.Singular,
                         CartTotal = cartTotal
                     };

两种视图模型如下:

public class AddressViewModel
{
    public string FirstAddressLine { get; set; }
    public string SecondAddressLine { get; set; }
    public string Town { get; set; }
    public string County { get; set; }
    public string PostCode { get; set; }
    public decimal Distance { get; set; } 
}

public class ShoppingCartViewModel
{
    public decimal? CartTotal { get; set; }
    public decimal? SweetTotal { get; set; }
    public bool? Singular { get; set; }              
    public decimal? Price { get; set; }
    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 string SweetName { get; set; }
}

但我不确定将 2 个视图模型返回到 1 个视图模型的最佳做法是什么?

编辑:如果我错过了明显的(仍在学习),但我不确定如何遵循您的答案,请道歉...我创建了购物车的部分视图:_ShoppingCartPartial,我已放置在共享视图文件夹中。

当我尝试在 Checkout 视图中呈现部分视图时,我收到了它所期望的错误 ShoppingCartViewModel,但我目前正在向它发送 AddressViewModel

我已经制作了两者的视图模型:

 public class CheckoutViewModel
{
    public IEnumerable<Address> AVM { get; set; }
    public IEnumerable<Cart> SCVM { get; set; }
}

问题是我不确定我应该将控制器(如下)更改为:

public ActionResult Index()
    {
        var CurrUser = User.Identity.GetUserId();
        var addDis = getAddDis(CurrUser);

        var result = from add in db.Addresses
                     join u in db.Users on add.UserID equals u.Id
                     where CurrUser == add.UserID
                     select new AddressViewModel
                     {
                        FirstAddressLine = add.FirstAddressLine,
                        SecondAddressLine = add.SecondAddressLine,
                        Town = add.Town,
                        PostCode = add.PostCode,
                        Distance = addDis
                     };


        return View(result);
    }

【问题讨论】:

  • 你必须将两个 ViewModel 添加到另一个 ViewModel 中
  • 使用 1 个视图和 2 个部分:1 个视图保存部分。您的数据的 2 个部分。将(具体)视图模型传递给每个 - @{ Html.RenderPartial("your view", your_model, ViewData);}

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


【解决方案1】:
  1. 为您的地址创建一个部分
  2. 为您的购物车创建一个部分

将它们放在您的视野中...

@model Something.Models.MyMainViewModel
<div>
    <div>
         @Html.Partial("~/Views/MyMain/AddressPartial.cshtml", Model.Address)
    </div>
    <div>
         @Html.Partial("~/Views/MyMain/ShoppingCartPartial.cshtml", Model.ShoppingCart)
    </div>
</div>

public class MyMainViewModel : ViewModelBase
{
    #region <Constructors>

    public MyMainViewModel(IApplication application, int id) : base(application)
    {
        Address = Application.GetAddress(id); //<-- From the base class
        ShoppingCart = Application.GetShoppingCart(id); //<-- From the base class
    }

    #endregion

    #region <Properties>

    public Address Address { get; set; }

    public ShoppingCart ShoppingCart { get; set; }

    #endregion
}

public class MainViewController : BaseController
{
    #region <Actions>

    [HttpGet]
    public ActionResult DoSomething(int id)
    {           
        var viewModel = new MyMainViewModel(application, id);

        return View("MyView", viewModel);
    }

    #endregion
}

public class ViewModelBase
{
    #region <Constructors>

    public ViewModelBase(IApplication application)
    {
        Application = (MyApplication)application;
    }

    #endregion

    #region <Properties>

    protected MyApplication Application { get; set; }

    #endregion
}

旁注:
考虑将所有 Linq 查询移至业务层,并让表示层简单地“与”业务(应用程序)层“对话”。这更加简洁,它使应用程序更“便携”并提高了可测试性。

  • 唯一需要注意的是,当 Linq 查询特定于表示层时......但老实说......这种情况应该很少见。

【讨论】:

  • 事实上,您不必使用两个局部视图...您可以在没有任何局部视图的单个视图中使用“MainViewModel”。但是当然,使用局部视图代码会更干净
【解决方案2】:

拥有一个包含两个子视图模型的主视图模型。这样的事情会起作用:

    public class SomePageViewModel
    {
        private IAddressService _addressService;
        private IShoppingCartService _shoppingCartService;

        public SomePageViewModel(
            IAddressService addressService,
            IShoppingCartService shoppingCartService)
        {
            _addressService = addressService;
            _shoppingCartService = shoppingCartService;
        }

        public async Task GetDataAsync()
        {
            Address = await _addressService.GetAddressViewModelAsync();
            ShoppingCart = await _shoppingCartService.GetShoppingCartAsync();
        }

        public AddressViewModel Address { get; private set; }

        public ShoppingCartViewModel ShoppingCart { get; private set; }
    }

您的 LINQ 语句将分别包含在 IAddressServiceIShoppingCartService 中(或者您可能会直接调用存储库)。

希望这会有所帮助。

【讨论】:

    【解决方案3】:

    创建一个包含其他两个视图模型的单一视图模型:

    public class FullViewModel {
        public AddressViewModel AddressModel { get; set; }
        public ShoppingCartViewModel ShoppingCartModel { get; set; }
    }
    

    然后返回那个模型。

    从那里你只需要创建两个部分:

    <div>
        @Html.Partial("[path]", Model.AddressModel)
        @Html.Partial("[path]", Model.ShoppingCartModel)
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 2016-02-05
      • 2019-10-03
      相关资源
      最近更新 更多