0

I'm building a feature with a jquery datatable, the idea is to have a list of stores in the parent row, and then when expanding the parent to list all the licensed terminals in child rows that are linked to the store parent row by a StoreLicenseId column. The issue I am having is that I have a ViewModel with two models, one for the list of stores and one for the licensed terminals. I'm busy building the method into my controller, my problem is in the second part of the method where I new up "StoreLicenseDetails = sl.Select(tl => new TerminalListViewModel()", all the references to tl.terminalId and tl.Terminalname. I get this error "StoreListViewModel does not contain a definition for TerminalID and no accessible extension method". I can see why this is happening, so my question really is, how do I include this "second" TerminalListViewModel into my method to form part of the query ?

ViewModel

 public partial class StoreListViewModel
    {
        public List<TerminalListViewModel> StoreLicenseDetails { get; set; } = null!;

        public int Id { get; set; }
        public Guid StoreLicenseId { get; set; }
        [DisplayName("Store Name")]
        public string StoreName { get; set; } = null!;
        [DisplayName("App One Licenses")]
        public int QtyAppOneLicenses { get; set; }
        [DisplayName("App Two Licenses")]
        public int QtyAppTwoLicenses { get; set; }
        [DisplayName("Date Licensed")]
        public DateTime DateLicensed { get; set; }
        [DisplayName("Licensed Days")]
        public int LicenseDays { get; set; }
        [DisplayName("Is License Active")]
        public bool LicenseIsActive { get; set; }
    }
    public partial class TerminalListViewModel
    {
        public int Id { get; set; }
        public Guid StoreLicenseId { get; set; }
        public Guid TerminalId { get; set; }
        public string TerminalName { get; set; } = null!;
        public string LicenseType { get; set; } = null!;
        public int TerminalLicenseDays { get; set; }
        public DateTime DateLicensed { get; set; }
        public bool LicenseIsActive { get; set; }
        public bool IsDecommissioned { get; set; }
        public DateTime LastLicenseCheck { get; set; }
    } 

Controller Method

//sl = StoreList
//tl = TerminalList
public IEnumerable<StoreListViewModel> GetStoreList()
{
    return GetStoreList().GroupBy(sl => new { sl.StoreLicenseId, sl.StoreName, sl.QtyAppOneLicenses, 
                                              sl.QtyAppTwoLicenses, sl.DateLicensed, sl.LicenseDays, 
                                              sl.LicenseIsActive })
        .Select(sl => new StoreListViewModel()
        {
            StoreName = sl.Key.StoreName,
            QtyAppOneLicenses = sl.Key.QtyAppOneLicenses,
            QtyAppTwoLicenses = sl.Key.QtyAppTwoLicenses,
            DateLicensed = sl.Key.DateLicensed,
            LicenseDays = sl.Key.LicenseDays,
            LicenseIsActive = sl.Key.LicenseIsActive,
            StoreLicenseId = sl.FirstOrDefault().StoreLicenseId,

            StoreLicenseDetails = sl.Select(tl => new TerminalListViewModel()
            {
                StoreLicenseId = tl.StoreLicenseId,
                TerminalId  = tl.TerminalId,
                TerminalName = tl.TerminalName,
            }).ToList()
        }).ToList();
}
jps
  • 20,041
  • 15
  • 75
  • 79
AlexJames
  • 55
  • 4
  • when you create a list of TerminalListViewModel, via a Select method, you effectively create a list of new objects. For those objects you need to provide all required properties, e.g. StoreLicenseID, TemrinalID, TerminalName. Currently you don't seem to have those fields available in your StoreListViewModel, hence you either need to retrieve them from some kind of a data source. Hard to say without seeing what you expect to put there. – mikus Oct 11 '22 at 14:03
  • The terminalId and TerminalName fields are available in the "TerminalListViewModel", but I can seem to access them. I'm trying to convert some code that I found online https://stackoverflow.com/questions/65410395/multiple-child-rows-in-datatable-data-from-sql-server-in-asp-net-core I need to do something very similar to this with my datatable. – AlexJames Oct 11 '22 at 19:33
  • 1
    you need to distinguish type definitions - TerminalListViewModel and StoreListViewModel and isntances of those types that actually hold the data. If you want to create a StoreListViewModel with a list of TerminalListViewModel in it, you need to have all the data accessible at the moment you're creating those object. So if your query starts from GetStoreList() this method should return objects that have all thast data. The fact that you're calling GetStoreList from GetStoreList method looks like a mistake btw, unless its a planned recursion. – mikus Oct 12 '22 at 11:41

1 Answers1

0

Based on the error,I suppose your GetStoreList() method returns List<OrderListViewModel> ,but your OrderListViewModel doesn't contains properties of TerminalListViewModel,So you got the error

enter image description here

GetStoreList() method should return List<SourceModel>( Source is the model which contains all the properties of StoreListViewModel and TerminalListViewModel)

For example,the link your provided:Multiple child rows in datatable, data from sql server in asp.net core

public class OrderList
    {
        //source of properties of OrderListViewModel(parent rows)
        public int OrderId { get; set; }
        public string Customer { get; set; }
        public string OrderDate { get; set; }

        //source of properties of OrderListDetailViewModel(child rows)
        public int KimlikId { get; set; }        
        public string Product { get; set; }
        public string Color { get; set; }
        public int Qntty { get; set; }
    }

    public class OrderListViewModel
    {
        public int OrderId { get; set; }
        public string Customer { get; set; }
        public string OrderDate { get; set; }
        public List<OrderListDetailViewModel> OrderListDetails { get; set; }

    }
    public class OrderListDetailViewModel
    {
        public int KimlikId { get; set; }
        public string Product { get; set; }
        public string Color { get; set; }
        public int Qntty { get; set; }
    }

Orderlist contains all columns OrderListViewModel and OrderListDetailViewModel needs.

When it comes to your case,you should

create 3 models (source,parentrow,childrows)

model for parentrows contains the properties

StoreLicenseId,StoreName, QtyAppOneLicenses,QtyAppTwoLicenses, DateLicensed, LicenseDays,LicenseIsActive

and model for childrows contains the other properties of source model

If you still have questions,please show the data you pulled form db,and I'll write a demo for you

Ruikai Feng
  • 6,823
  • 1
  • 2
  • 11
  • Hi Ruikai Feng, thank you so much for you excellant explanation, it really helped me to fix my ViewModel and the method,a s well as understand what I needed to do. The JavaScript that loads the grid isnt working and my datatable is either empty or the app crashed without errors, but I'll start a new thread for that. – AlexJames Oct 12 '22 at 12:43