Как отобразить составной список из модели в модели страницы другой модели? - PullRequest
1 голос
/ 21 января 2020

На главной странице указателя я хотел бы отобразить список сотрудников в столбце «Имя сотрудника». то есть Томми Багамские Острова, Клинтон К. и др. c ...

У меня возникли трудности, поскольку таблица Officer и SecurityLogOfficer не являются частью моей модели SecurityLog на странице индекса.

Страница индекса SecurityLog

@foreach (var item in Model.SecurityLog)
    {
    <tr>
        <td style="width:4% !important">
            @Html.DisplayFor(modelItem => item.ID)
        </td>
        <td style="width:5% !important">
            @Html.DisplayFor(modelItem => item.EventDate)
        </td>


        <td style="width:5% !important">
            @Html.DisplayFor(modelItem => item.OfficerList)
        </td>
}

Я создал класс OfficerList для возврата списка разделенных запятыми офицеров, но у меня возникают проблемы с отображением этого на странице индекса SecurityLog.

public class OfficerList : SecurityLog
{
    private readonly SecurityCore.Models.SecurityCoreContext _context;

    public OfficerList(SecurityCore.Models.SecurityCoreContext context)
    {
        _context = context;
    }

    public List<string> GetOfficerList()
    {
        List<string> OfficerIDs = new List<string>();

        //use the syntax .ToList() to convert object read from db to list to avoid being re-read again
        var SecLog = _context.SecurityLog.ToList();
        var SecLogOfficer = _context.SecurityLogOfficer.ToList();
        var Officer = _context.Officer.ToList();


        int rowID;

        //string[] OfficerIDs = new string[100];
        rowID = 0;

        foreach (SecurityLog sl in SecLog)
        {
            foreach (SecurityLogOfficer slo in SecLogOfficer.Where(slo => slo.SecurityLogID == sl.ID))
            {
                if (OfficerIDs[rowID] == null)
                {
                    OfficerIDs[rowID] = slo.Officer.FullName + ", ";
                }
                else
                {
                    OfficerIDs[rowID] = OfficerIDs[rowID] + slo.Officer.FullName + ", ";
                }
            }

            rowID++;
        }

        return OfficerIDs;

    }

} 

Здесь я хотел бы отобразить составной список ...

enter image description here

А вот моя схема базы данных и пример результаты

Sql Database Schema

Любая помощь будет принята с благодарностью. Спасибо!

ОБНОВЛЕНИЕ

У меня проблема с получением списка составных имен в моей модели SecurityLog.

public class SecurityLog
{
    private readonly SecurityCore.Models.SecurityCoreContext _context;

    public SecurityLog(SecurityCore.Models.SecurityCoreContext context)
    {
        _context = context;
    }

   ......

    public List<string> OfficerList
    {            
        get
        {                                
            var officerList = new OfficerList(_context);                

            return officerList.GetOfficerList();
        }
    }


 }

Изменено Класс OfficerList

public class OfficerList : SecurityLog
{
private readonly SecurityCore.Models.SecurityCoreContext _context;

public OfficerList(SecurityCoreContext context) : base(context)
{
    _context = context;
}

public List<string> GetOfficerList()
{
    List<string> OfficerIDs = new List<string>();

    //use the syntax .ToList() to convert object read from db to list to avoid being re-read again
    var SecLog = _context.SecurityLog.ToList();
    var SecLogOfficer = _context.SecurityLogOfficer.ToList();
    var Officer = _context.Officer.ToList();


    int rowID;

    //string[] OfficerIDs = new string[100];
    rowID = 0;

    foreach (SecurityLog sl in SecLog)
    {
        foreach (SecurityLogOfficer slo in SecLogOfficer.Where(slo => slo.SecurityLogID == sl.ID))
        {
            if (OfficerIDs[rowID] == null)
            {
                OfficerIDs[rowID] = slo.Officer.FullName + ", ";
            }
            else
            {
                OfficerIDs[rowID] = OfficerIDs[rowID] + slo.Officer.FullName + ", ";
            }
        }

        rowID++;
    }

    return OfficerIDs;

}

}

Мой _context для SecurityLog говорит, что он нулевой.

SqlNullValueException: данные равны нулю. Этот метод или свойство нельзя вызывать для значений Null. Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull () Microsoft.Data.SqlClient.SqlBuffer.get_DateTime () Microsoft.Data.SqlClient.SqlDataReader. ) Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable + Enumerator.MoveNext () System.Collections.Generi c .List..ctor (IEnumerable collection) System.Linq.Enumerable.ToList (IEnumerable source) SecurityCore.Models. SecurityCore.Models. GetOfficerList () в OfficerList.cs + var SecLog = _context.SecurityLog.ToList (); SecurityCore.Models.SecurityLog.get_OfficerList () в SecurityLog.cs + return employeeList.GetOfficerList (); Microsoft.AspNetCore. Mvc .ViewFeatures.ExpressionMetadataProvider + <> c__DisplayClass0_0.g__modelAccessor | 0 (контейнер объектов). Microsoft.AspNetCore. Mvc .ViewFeatures.ModelExplorer.get_Model () Microsoft.AeSe. ctor (IViewEngine viewEngine, IViewBufferScope bufferScope, ViewContext viewContext, ViewDataDictionary viewData, ModelExplorer modelExplorer, строка htmlFieldName, строка templateName, bool readOnly, объект AdditionalViewData) Microsoft.AspNetCore. stringFlay.HelE.GerF. templateName, объект AdditionalViewData) Microsoft.AspNetCore. Mvc .ViewFeatures.HtmlHelper.DisplayFor (выражение> выражение, строка templateName, строка htmlFieldName, объект AdditionalViewData) Microsoft.AspNetCore. Mvc .Rendering.HtmlHelperDisplayExperressionHHperperHisplayHerperHisperHerperHisperHerperHisperHerperHisperHerperHisperHerperHisperHerperHisperHerperHisperHerperHerplayHeperHellHellHellHellHellHellHellHellHerHerHerHerperHerperHerperHerperHerperHerperHerperHerperHerperHerperHerperHelperHer > выражение) SecurityCore.Pages.SecurityLogs.Pages_SecurityLogs_Index.ExecuteAsyn c () в Index.cshtml + @ Html .DisplayFor (modelItem => item.OfficerList) Microsoft.AspNetCore. Mvc .Razor.RazorView.RenderPageCoreAsyn c (страница IRazorPage, контекст представления контекста) Microsoft.AspNetCore. Mvc .Razor.RazorView.RenderPageAsyn c (страница IRazorPage, контекст ViewContext, bool invokeViewStarts) Microsoft.AspNetCore. Mvc .Razor.RazorView.RenderAsyn c (контекст ViewContext) Microsoft.AspNetCore. * 10at *. .ViewExecutor.ExecuteAsyn c (ViewContext viewContext, строка contentType, Nullable statusCode) Microsoft.AspNetCore. Mvc .ViewFeatures.ViewExecutor.ExecuteAsyn c (ViewContext viewContext, строка contentType, Nullable statusCoreCode.Code). .Infrastructure.ResourceInvoker.g__Awaited | 29_0 (ResourceInvoker invoker, Task LastTask, State next, Область действия, состояние объекта, bool isCompleted) Microsoft.AspNetCore. Mvc .Infrastructure.ResourceInvoker.Rethrow (ResultExecutedContext.ealed context.e2. Context.ealedNet) .Cecaled context.ealedNet) .Console.). * .Infrastructure. ResourceInvoker.ResultNext (ref State next, ref Область действия, ref object object, ref bool isCompleted). Microsoft.AspNetCore. Mvc .Infrastructure.ResourceInvoker.InvokeResultFilters () Microsoft.AspNetCore. Mvc .Infrastructure.ResourceInvoker__ (ResourceInvoker invoker, Task lastTask, State next, Область действия, состояние объекта, bool isCompleted). Microsoft.AspNetCore. Mvc .Infrastructure.ResourceInvoker.Rethrow (контекст ResourceExecutedContextSealed) Microsoft.AspNetCore. Mvc .Infrastructure.Resource. ref State next, ref Область действия, состояние объекта ref, ref bool isCompleted) Microsoft.AspNetCore. Mvc .Infrastructure.ResourceInvoker.g__Awaited | 19_0 (Вызов ResourceInvoker, задача lastTask, следующее состояние, область действия Scope, состояние объекта, bool isCompleted) Microsoft.AspNetCore. Mvc .Infrastructure.ResourceInvoker.g__Logged | 17_1 (ResourceInvoker invoker) Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask | 6_0 (конечная точка конечной точки, задача requestTask, ILogger logger) Micros t.AspNetCore.Authorization.AuthorizationMiddleware.Invoke (контекст HttpContext) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke (контекст HttpContext)

ОБНОВЛЕНИЕ 1052 public class SecurityCoreContext : DbContext { public SecurityCoreContext (DbContextOptions<SecurityCoreContext> options) : base(options) { } public DbSet<SecurityCore.Models.SecurityLog> SecurityLog { get; set; } public DbSet<SecurityCore.Models.Entity> Entity { get; set; } public DbSet<SecurityCore.Models.Location> Location { get; set; } public DbSet<SecurityCore.Models.ShiftRange> ShiftRange { get; set; } public DbSet<SecurityCore.Models.EventType> EventType { get; set; } public DbSet<SecurityCore.Models.SecurityLogOfficer> SecurityLogOfficer { get; set; } public DbSet<SecurityCore.Models.Officer> Officer { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<SecurityLogOfficer>() .HasKey(t => new { t.SecurityLogID, t.OfficerID }); modelBuilder.Entity<SecurityLogOfficer>() .HasOne(pt => pt.SecurityLog) .WithMany(p => p.SecurityLogOfficers) .HasForeignKey(pt => pt.SecurityLogID); modelBuilder.Entity<SecurityLogOfficer>() .HasOne(pt => pt.Officer) .WithMany(t => t.SecurityLogOfficers) .HasForeignKey(pt => pt.OfficerID); } } ОБНОВЛЕНИЕ 1/23/2020

Я попытался обновить код, основываясь на ответе ниже, и я думаю, что это действительно близко к решению; внутри класса OfficerList в настоящее время нет значения для SecLog b / c нет данных о загрузке страницы, пока не нажата кнопка поиска.

 OfficerList officerList = new OfficerList();
 OfficerLists = officerList.GetOfficerList(_context);

 SecurityLog = await PaginatedList<SecurityLog>.CreateAsync(sort
    .Include(a => a.Entity)
    .Include(b => b.EventType)
    .Include(c => c.Location)
    .Include(d => d.ShiftRange)
    .Include(e => e.Officer)
    .AsNoTracking(), pageIndex ?? 1, pageSize);

Это значение равно нулю при переходе к Класс OfficerList

var SecLog = _context.SecurityLog.ToList();

SqlNullValueException: данные равны нулю. Этот метод или свойство нельзя вызывать для значений Null. Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull () Microsoft.Data.SqlClient.SqlBuffer.get_DateTime () Microsoft.Data.SqlClient.SqlDataReader. ) Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable + Enumerator.MoveNext () System.Collections.Generi c .List..ctor (IEnumerable collection) System.Linq.Enumerable.ToList (IEnumerable source) SecurityCore.Models. SecurityCore.Models. GetOfficerList (SecurityCoreContext _context) в OfficerList.cs + var SecLog = _context.SecurityLog.ToList (); SecurityCore.Pages.SecurityLogs.IndexModel.OnGetAsyn c (строка sortOrder, строка currentFilter, строка searchString, Nullable pageIndex, строка entitySelect, строка entityFilter, DateTime dateBegin, DateTime dateBeginSelect, DateTime dateEnd.In DateSide * DateSime * DateNime12, DateSime * 12) в DateTime DateDend, DateSime * 11 в DateTime, DateTime, 1112) .cs + OfficerLists = employeeList.GetOfficerList (_context);

Есть ли в классе OfficerList способ не l oop через SecurityLog в foreach и каким-то образом передать идентификатор ID SecurityLog как второй параметр для OfficerList (вместе с _context)?

enter image description here

Ответы [ 2 ]

1 голос
/ 29 января 2020

Мне удалось изменить предложенный @Yongqing Yu код, чтобы список офицеров отображался корректно. Я решил передать идентификатор классу OfficerList, и сортировка настроена так, чтобы я получал правильный список офицеров для каждой строки.

Я изначально не публиковал этот лог c, но у меня есть сортировка, поиск и пейджинг, который я смог реализовать на основе демонстрации Microsoft Contoso University.
https://docs.microsoft.com/en-us/aspnet/core/data/ef-rp/sort-filter-page?view=aspnetcore-3.1

С недавно внедренным кодом сортировка и фильтрация больше не работает для списка офицеров. Все остальное работает как нужно.

Как я могу решить сортировку и поиск в моем текущем коде ниже? и более конкретно ... как я могу прочитать (выполнить итерацию) список OfficerID и найти строковое значение каждого элемента списка (строка связанного списка офицеров)?

foreach (SecurityLog secLog in SecurityLog)
        {
            secLogCopy = secLog;

            OfficerLists = officerList.GetOfficerList(_context, secLog, rowID, OfficerIDs);
            if (!String.IsNullOrEmpty(searchString))
            {
                sort = sort.Where(s => OfficerIDs.ToString().Contains(searchString));
            }
            rowID++;
        }

PageModel:

namespace SecurityCore.Pages.SecurityLogs
{
    public class IndexModel : PageModel
    {
        private readonly SecurityCore.Models.SecurityCoreContext _context;

        public IndexModel(SecurityCore.Models.SecurityCoreContext context)
        {
            _context = context;
        }

        public string EventDateSort { get; set; }
        public string EventStartSort { get; set; }
        public string EventEndSort { get; set; }
        public string ContactNameSort { get; set; }
        public string EventTypeSort { get; set; }
        public string ShiftRangeSort { get; set; }

        public string CurrentSort { get; set; }
        public string IDSort { get; set; }

        [DataType(DataType.Date)]
        public Nullable<DateTime> DateEnd { get; set; }
        [DataType(DataType.Date)]
        public Nullable<DateTime> DateBegin { get; set; }
        public Entity Entity { get; set; }


        public PaginatedList<SecurityLog> SecurityLog { get; set; }
        public List<secLog> SecurityLogOfficers { get; set; } = new List<secLog>();
        public List<string> OfficerLists { get; set; }

        [BindProperty]
        public OfficerList officerList { get; set; } = new OfficerList();
        [BindProperty]
        public List<string> OfficerIDs { get; set; } = new List<string>();







    public async Task OnGetAsync(string sortOrder, string currentFilter, string searchString, int? pageIndex,
                                 string entitySelect, string entityFilter, DateTime dateBegin, DateTime dateBeginSelect, DateTime dateEnd, DateTime dateEndSelect)
    {
        selectedEntity = new SelectList(_context.Entity.Where(a => a.Active == "Y"), "Name", "Name");

        CurrentSort = sortOrder;
        IDSort = sortOrder == "ID" ? "ID_Desc" : "ID";
        EventDateSort = sortOrder == "EventDate" ? "EventDate_Desc" : "EventDate";
        ContactNameSort = sortOrder == "ContactName" ? "ContactName_Desc" : "ContactName";
        EventTypeSort = sortOrder == "EventType" ? "EventType_Desc" : "EventType";
        ShiftRangeSort = sortOrder == "ShiftRange" ? "ShiftRange_Desc" : "ShiftRange";            
        OfficerNameSort = sortOrder == "OfficerName" ? "OfficerName_Desc" : "OfficerName";


        IQueryable<SecurityLog> sort = from s in _context.SecurityLog select s;


        switch (sortOrder)
        {
            case "ID_Desc":
                sort = sort.OrderByDescending(s => s.ID);
                break;
            case "ID":
                sort = sort.OrderBy(s => s.ID);
                break;
            case "EventDate":
                sort = sort.OrderBy(s => s.EventDate);
                break;                
            case "ShiftRange":
                sort = sort.OrderBy(s => s.ShiftRange.Name).ThenBy(s => s.EventDate);
                break;
            case "ShiftRange_Desc":
                sort = sort.OrderByDescending(s => s.ShiftRange.Name).ThenBy(s => s.EventDate);
                break;
            case "EventType":
                sort = sort.OrderBy(s => s.EventType.Name).ThenBy(s => s.EventDate);
                break;
            case "EventType_Desc":
                sort = sort.OrderByDescending(s => s.EventType.Name).ThenBy(s => s.EventDate);
                break;                
            case "OfficerName":                    
                sort = sort.OrderBy(s => officerList.ToString()).ThenBy(s => s.EventDate);
                break;
            case "OfficerName_Desc":                    
                sort = sort.OrderByDescending(s => officerList.ToString()).ThenBy(s => s.EventDate);
                break;
            default:
                sort = sort.OrderByDescending(s => s.EventDate);
                break;
        }

        int pageSize = 5;





        SecurityLog = await PaginatedList<SecurityLog>.CreateAsync(sort
        .Include(a => a.Entity)
        .Include(b => b.EventType)
        .Include(c => c.Location)
        .Include(d => d.ShiftRange)
        .Include(e => e.Officer)                                    
        .AsNoTracking(), pageIndex ?? 1, pageSize);



        int rowID;
        rowID = 0;


        foreach (SecurityLog secLog in SecurityLog)
        {
            secLogCopy = secLog;
            OfficerLists = officerList.GetOfficerList(_context, secLog, rowID, OfficerIDs);
            if (!String.IsNullOrEmpty(searchString))
            {
                sort = sort.Where(s => OfficerIDs.ToString().Contains(searchString));
            }
            rowID++;
        }



        if (!String.IsNullOrEmpty(searchString))
        {                                                

            sort = sort.Where(s => s.Narrative.Contains(searchString)
                                || s.RecordLocked.Contains(searchString)
                                || s.ContactName.Contains(searchString)
                                || s.Location.Name.Contains(searchString)
                                || s.EventType.Name.Contains(searchString)
                                || s.ShiftRange.Name.Contains(searchString)
                                || s.ID.ToString().Contains(searchString)
                                || s.SubjectFirst.Contains(searchString)
                                || s.SubjectLast.Contains(searchString));                                    
        }

    }

}

}

OfficerList.cs

public class OfficerList
{
    public List<string> GetOfficerList(SecurityCoreContext _context, SecurityLog secLog, int rowID, List<string> OfficerIDs)
    {            

        int CurrentID = secLog.ID;

        var SecLogOfficer = _context.SecurityLogOfficer.ToList();
        var Officer = _context.Officer.ToList();


        int count = SecLogOfficer.Where(slo => slo.SecurityLogID == CurrentID).Count();

        if (count >= 0)
        {
            OfficerIDs.Add("");
        }
        foreach (secLog slo in SecLogOfficer.Where(slo => slo.SecurityLogID == CurrentID))
        {
            OfficerIDs[rowID] = OfficerIDs[rowID] + slo.Officer.FullName + ", ";
        }
        if (count > 0)
        {
            OfficerIDs[rowID] = OfficerIDs[rowID].Substring(0, OfficerIDs[rowID].Length - 2);
        }


        return OfficerIDs;

    }

}

Страница:

@page
@model WebApplication_core_razorpage.Pages.HomeModel
@{
    ViewData["Title"] = "Home";
    Layout = "~/Pages/Shared/_Layout.cshtml";
    var i = 0;
}

<h1>Home</h1>

<table>
    @foreach (var item in Model.SecurityLog)
    {
        <tr>
            <td style="width:4% !important">
                @Html.DisplayFor(modelItem => item.ID)
            </td>
            <td style="width:5% !important">
                @Html.DisplayFor(modelItem => item.EventDate)
            </td>

            <td style="width:5% !important">
                @Model.OfficerLists[i]
            </td>
        </tr>
        i++;
    }

</table>

PaginatedList.cs

public class PaginatedList<T> : List<T>
{
    public int PageIndex { get; private set; }
    public int TotalPages { get; private set; }        

    public PaginatedList(List<T> items, int count, int pageIndex, int pageSize)
    {
        PageIndex = pageIndex;
        TotalPages = (int)Math.Ceiling(count / (double)pageSize);

        this.AddRange(items);
    }

    public bool HasPreviousPage
    {
        get
        {
            return (PageIndex > 1);
        }
    }


    public bool HasNextPage => PageIndex < TotalPages;

    public bool ShowFirst
    {
        get
        {
            return (PageIndex != 1);
        }
    }

    public bool ShowLast
    {
        get
        {
            return (PageIndex != TotalPages);
        }
    }

    public static async Task<PaginatedList<T>> CreateAsync(
        IQueryable<T> source, int pageIndex, int pageSize)
    {
        var count = await source.CountAsync();
        var items = await source.Skip(
            (pageIndex - 1) * pageSize)
            .Take(pageSize).ToListAsync();
        return new PaginatedList<T>(items, count, pageIndex, pageSize);
    }
}
1 голос
/ 23 января 2020

Я обнаружил, что вы многократно использовали внедрение зависимостей в классах OfficeList и SecurityLog. Это должно быть основной причиной ошибки

. Я полагаю, что вам нужно использовать только внедрение зависимостей в PageModel, передавать _context в качестве параметра методу GetOfficerList, и я не думаю, что вам нужно разрешать OfficeList наследует класс SecurityLog.

После возврата коллекции OfficeID используйте поле OfficerLists в PageModel, чтобы сохранить коллекцию, и сохраните коллекцию данных SecurityLog в поле SecurityLog.

В том же самом время я нашел несколько ошибок в вашем методе GetOfficerList. Для тестирования можно напрямую обратиться к следующему коду:

PageModel:

public class HomeModel : PageModel
{ 
    private readonly SecurityCoreContext _context;
    public HomeModel(SecurityCoreContext context)
    {
        _context = context;
    }

    public List<string> OfficerLists { get; set; }
    public IList<SecurityLog> SecurityLog { get; set; }

    public async Task<IActionResult> OnGetAsync()
     {
        OfficerList officerList = new OfficerList();
        OfficerLists = officerList.GetOfficerList(_context);
        SecurityLog = await _context.SecurityLog.AsNoTracking().ToListAsync();
        return Page();
    }
}

OfficerList.cs

public class OfficerList
{
    public List<string> GetOfficerList(SecurityCoreContext _context)
    {
        List<string> OfficerIDs = new List<string>();

        //use the syntax .ToList() to convert object read from db to list to avoid being re-read again
        var SecLog = _context.SecurityLog.ToList();
        var SecLogOfficer = _context.SecurityLogOfficer.ToList();
        var Officer = _context.Officer.ToList();

        int rowID;
        rowID = 0;
        foreach (SecurityLog sl in SecLog)
        {
            int count = SecLogOfficer.Where(slo => slo.SecurityLogID == sl.ID).Count();
            if (count > 0)
            {
                OfficerIDs.Add("");
            }
            foreach (SecurityLogOfficer slo in SecLogOfficer.Where(slo => slo.SecurityLogID == sl.ID))
            {
                OfficerIDs[rowID] = OfficerIDs[rowID] + slo.Officer.FirstName + ", ";
            }
            if (count > 0)
            {
                OfficerIDs[rowID] = OfficerIDs[rowID].Substring(0, OfficerIDs[rowID].Length - 2);
            }
            rowID++;
        } 
        return OfficerIDs;

    }
}

Страница:

@page
@model WebApplication_core_razorpage.Pages.HomeModel
@{
    ViewData["Title"] = "Home";
    Layout = "~/Pages/Shared/_Layout.cshtml";
    var i = 0;
}

<h1>Home</h1>

<table>
    @foreach (var item in Model.SecurityLog)
    {
        <tr>
            <td style="width:4% !important">
                @Html.DisplayFor(modelItem => item.ID)
            </td>
            <td style="width:5% !important">
                @Html.DisplayFor(modelItem => item.EventDate)
            </td>

            <td style="width:5% !important">
                @Model.OfficerLists[i]
            </td>
        </tr>
        i++;
    }

</table>

Вот результат этой демонстрации:

https://i.stack.imgur.com/sz2LA.png

...