0

On an ASP Core project I have a model for Customers:

using System;
using System.Collections.Generic;

namespace RiskDotNet.Models
{
    public partial class Customers
    {
        public Customers()
        {
            Accounts = new HashSet<Accounts>();
        }

        public string SrcSys { get; set; }
        public string CustId { get; set; }
        public string CustNm { get; set; }

        public virtual ICollection<Accounts> Accounts { get; set; }
    }
}

Thereafter, the accounts pertaining to each customer as:

using System;
using System.Collections.Generic;

namespace RiskDotNet.Models
{
    public partial class Accounts
    {
        public Accounts()
        {
            Balances = new HashSet<Balances>();
        }

        public string SrcSys { get; set; }
        public string CustId { get; set; }
        public string AccId { get; set; }
        public string ProdId { get; set; }

        public virtual ICollection<Balances> Balances { get; set; }
        public virtual Customers Customers { get; set; }
    }
}

And third model for the balances (transactions) pertaining to each account:

using System;
using System.ComponentModel.DataAnnotations;

namespace RiskDotNet.Models
{
    public partial class Balances
    {
        [DisplayFormat(DataFormatString = "{0:dd-MMM-yyyy}")]
        public DateTime RepDt { get; set; }
        public string CustId { get; set; }
        public string AccId { get; set; }
        public string SrcSys { get; set; }
        public decimal? PrOs { get; set; }

        public virtual Accounts X { get; set; }
    }
}

Now, while I want the Balances table, in the details view of the Accounts page, to be reflected in a sorted manner like a Descending Order of the Reporting Date (RepDt), I am unable to do so.

What is wrong with the following details section of the Accounts Controller:

    public async Task<IActionResult> Details(string _SrcSys, string _CustId, string _AccId) //All three join up to form the Composite Key
    {
        if (_SrcSys == null || _CustId == null || _AccId == null)
        {
            return NotFound();
        }

        var Accs = await _context.Accounts
            .Include(Cust => Cust.Customers) //To reflect the Customer's Name
            .Include(Bal => Bal.Balances) //The Main Portion I want sorted
            .SingleOrDefaultAsync(m => m.SrcSys == _SrcSys && m.CustId == _CustId && m.AccId == _AccId);
        return View(Accs.Balances.OrderByDescending(x => x.RepDt));
    }

Error returns stack:

InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Linq.OrderedEnumerable`2[RiskDotNet.Models.Balances,System.DateTime]', but this ViewDataDictionary instance requires a model item of type 'RiskDotNet.Models.Accounts'.

Follows the View Model:

@model RiskDotNet.Models.Accounts
@{ViewData["Title"] = "Details";}
<div>
        <dt><strong>Account:</strong></dt>
        <dd>@Html.DisplayFor(model => model.AccId)</dd>
        <dt><strong>Src. System:</strong></dt>
        <dd>@Html.DisplayFor(model => model.SrcSys)</dd>
        <dt><strong>Product:</strong></dt>
        <dd>@Html.DisplayFor(model => model.ProdId)</dd>
    </dl>
</div>
<div>
    <dl>
        <dd>
            <table class="table">
                <tr>
                    <th>Date</th>
                    <th style="text-align:right">Pr. O/s.</th>
                </tr>
                @foreach (var item in Model.Balances)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.RepDt)
                        </td>
                        <td style="text-align:right">
                            @Html.DisplayFor(modelItem => item.PrOs)
                        </td>
                    </tr>
                }
            </table>
        </dd>
    </dl>
</div>
    <a asp-action="Index">Accounts' List</a>
InAction
  • 45
  • 6
  • You have not shown your view but clearly it has `@model Accounts` but your passing a collection of `Balances` to it. They need to be the same. Refer [The model item passed into the dictionary is of type .. but this dictionary requires a model item of type](http://stackoverflow.com/questions/40373595/the-model-item-passed-into-the-dictionary-is-of-type-but-this-dictionary-requ) –  May 20 '17 at 22:23
  • I have added the model. No doubt I used the @model. But the referred source didn't help and I couldn't catch the error. Please see if you can help. The main object is to have the balances' list be presented in a sorted manner on the details page of the accounts. While simple **return View(Accs);** works well – InAction May 21 '17 at 06:54
  • Read it again carefully! Your not passing a collection of `Accounts` to the view - your passing a collection of `Balances` –  May 21 '17 at 06:57
  • Stephene, no doubt its **Balances** to the **Accounts** view but then what would be the correct LINQ to include the relevant Balances entries and also have it sorted? – InAction May 21 '17 at 07:06
  • I suspect you probably want something like `return View(Accs.OrderBy(x => x.Balances.OrderBy(y => y.RepDt));` –  May 21 '17 at 07:10
  • Nopes! The very first OrderBy highlighted complaining Accounts to be not containing a definition for 'OrderBy'. Thanks anyway. – InAction May 21 '17 at 07:25
  • Sorry, did not notice you were selecting only one `Account`. Put that in your query before you call `.SingleOrDefaultAsync(...)` –  May 21 '17 at 07:30
  • Sorry, But, what to place before calling the SingleOrDefaultAsync? The Return View statement? – InAction May 21 '17 at 07:51
  • I meant `var Accs = await _context.Accounts.Include(..).Include(..).OrderBy(x => x.Balances.OrderByDecsending(y => y.RepDt)).SingleOrDefaultAsync(..); return View(Accs);` –  May 21 '17 at 07:53
  • Nopes again! Although the page loaded correctly the table remains to be unsorted. I guess the LINQ is unable to sort an .include query here. – InAction May 21 '17 at 08:02
  • @InAction This should solve your problem. var Accs = await _context.Accounts .Include(Cust => Cust.Customers) .Include(Bal => Bal.Balances) .OrderBy(x => x.Balances.OrderByDecsending(y => y.RepDt)) .SingleOrDefaultAsync(m => m.SrcSys == _SrcSys && m.CustId == _CustId && m.AccId == _AccId); return View(Accs); – IdahoSixString Jun 06 '17 at 19:53
  • @InAction Alternatively you can also do it in the view. foreach (var item in Model.Balances.OrderByDecsending(y => y.RepDt)) – IdahoSixString Jun 06 '17 at 19:55

0 Answers0