在我的主索引页面中,我想在“人员姓名”列中显示人员列表。即Tommy Bahamas,Clinton K等...
我遇到了麻烦,因为在索引页上,“官员”和“ 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的类,以返回以逗号分隔的Officer列表,但是我无法在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;
}
}
这是我要显示串联列表的地方...
这是我的数据库架构和示例结果
任何帮助将不胜感激。谢谢!
更新
我在检索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;
}
}
我对SecurityLog的_context表示它为空。
SqlNullValueException:数据为Null。此方法或属性不能为 调用Null值。 Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull() Microsoft.Data.SqlClient.SqlBuffer.get_DateTime() Microsoft.Data.SqlClient.SqlDataReader.GetDateTime(int i) lambda_method(Closure,QueryContext,DbDataReader,ResultContext, int [],ResultCoordinator) Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable + Enumerator.MoveNext() System.Collections.Generic.List..ctor(IEnumerable集合) System.Linq.Enumerable.ToList(IEnumerable源) OfficerList.cs中的SecurityCore.Models.OfficerList.GetOfficerList() + var SecLog = _context.SecurityLog.ToList(); SecurityLog.cs中的SecurityCore.Models.SecurityLog.get_OfficerList() + 返回OfficerList.GetOfficerList(); Microsoft.AspNetCore.Mvc.ViewFeatures.ExpressionMetadataProvider + <> c__DisplayClass0_0.g__modelAccessor | 0(对象容器) Microsoft.AspNetCore.Mvc.ViewFeatures.ModelExplorer.get_Model() Microsoft.AspNetCore.Mvc.ViewFeatures.TemplateBuilder..ctor(IViewEngine viewEngine,IViewBufferScope bufferScope,ViewContext viewContext, ViewDataDictionary viewData,ModelExplorer,modelExplorer,字符串 htmlFieldName,字符串templateName,bool readOnly,object AdditionalViewData) Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.GenerateDisplay(ModelExplorer modelExplorer,字符串htmlFieldName,字符串templateName,对象 AdditionalViewData) Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.DisplayFor(Expression>表达式,字符串templateName,字符串htmlFieldName, 对象AdditionalViewData) Microsoft.AspNetCore.Mvc.Rendering.HtmlHelperDisplayExtensions.DisplayFor(IHtmlHelper htmlHelper,Expression>表达式) SecurityCore.Pages.SecurityLogs.Pages_SecurityLogs_Index.ExecuteAsync() 在Index.cshtml中 + @ Html.DisplayFor(modelItem => item.OfficerList)Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageCoreAsync(IRazorPage 页面,ViewContext上下文) Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderPageAsync(IRazorPage 页,ViewContext上下文,布尔invokeViewStarts) Microsoft.AspNetCore.Mvc.Razor.RazorView.RenderAsync(ViewContext 上下文) Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext,字符串contentType,可空statusCode) Microsoft.AspNetCore.Mvc.ViewFeatures.ViewExecutor.ExecuteAsync(ViewContext viewContext,字符串contentType,可空statusCode) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited | 29_0(ResourceInvoker调用程序,任务lastTask,状态下一个, 作用域作用域,对象状态,布尔值已完成) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed 上下文) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext(下一个参考状态,参考作用域范围,参考对象状态,参考 bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters() Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited | 24_0(ResourceInvoker 调用者,任务lastTask,状态下一个,作用域范围,对象状态,布尔 完成了) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed 上下文) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(参考状态 接下来,ref Scope范围,ref对象状态,ref bool isCompleted) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited | 19_0(ResourceInvoker 调用者,任务lastTask,状态下一个,作用域范围,对象状态,布尔 完成了) Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Logged | 17_1(ResourceInvoker 调用者) Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask | 6_0(Endpoint 端点,任务请求任务,ILogger记录器) Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext 上下文) Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext 上下文)
更新-添加关系
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);
}
}
更新2020年1月23日
我试图根据以下答案更新代码,但是我认为这真的很接近要解决。在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。不能在Null值上调用此方法或属性。 Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull() Microsoft.Data.SqlClient.SqlBuffer.get_DateTime() Microsoft.Data.SqlClient.SqlDataReader.GetDateTime(int i) lambda_method(Closure,QueryContext,DbDataReader,ResultContext, int [],ResultCoordinator) Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable + Enumerator.MoveNext() System.Collections.Generic.List..ctor(IEnumerable集合) System.Linq.Enumerable.ToList(IEnumerable源) SecurityCore.Models.OfficerList.GetOfficerList(SecurityCoreContext _context)在OfficerList.cs中 + var SecLog = _context.SecurityLog.ToList(); SecurityCore.Pages.SecurityLogs.IndexModel.OnGetAsync(string sortOrder,字符串currentFilter,字符串searchString,Nullable pageIndex,字符串entitySelect,字符串entityFilter,DateTime dateBegin,DateTime dateBeginSelect,DateTime dateEnd,DateTime index.cshtml.cs中的dateEndSelect) + OfficerLists = OfficerList.GetOfficerList(_context);
OfficialList类中是否有一种方法可以不遍历foreach中的SecurityLog,并以某种方式将SecurityLog的ID作为第二个参数传递给OfficerList(和_context)?
答案 0 :(得分:1)
我发现您在OfficeList和SecurityLog类中多次使用了依赖项注入。这应该是导致错误的主要原因
我建议您只需在PageModel中使用依赖项注入,将_context作为参数传递给GetOfficerList方法,并且我认为不需要让OfficeList继承SecurityLog类。
返回OfficeIDs集合后,请使用PageModel中的OfficerLists字段来存储集合,并将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>
这是此演示的结果:
答案 1 :(得分:1)
我能够修改@Yongqing Yu的建议代码,以使军官列表正确显示。我决定将ID传递给OfficerList类,并进行排序设置,以便为每一行获取正确的官员列表。
我最初并未发布此逻辑,但是我可以基于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);
}
}