如何在 blazor 中显示属于某个组的组成员列表?

How do I show a list of group members that belong to a group in blazor?

下面是我的群友Class

namespace MMSProjectShared
{
    public  class GroupMember
    {
        [Key]
        public int MemberId { get; set; }
        public int MemberNumber { get; set; }
        public string Nrc { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
        public string PhoneNumber { get; set; }
        public int GroupId { get; set; }
        public Group Group { get; set; }
    }
}

这是我的群组class

namespace MMSProjectShared
{
    public class Group
    {
        [Key]
        public int GroupId { get; set; }
        public string GroupName { get; set; }
        public string Product_Service { get; set; }
        public List<GroupMember> GroupMembers { get; set; }
        public int CategoryId { get; set; }
        public Category Category { get; set; }   
        public ICollection<Loan> Loan { get; set; }


    }
}

我希望能够在群组页面中显示群组成员,如下所示: 我在 DotNet 6 上使用 blazorServer。

这是我尝试过的:

<MudTd DataLabel="GroupMembers">
            @foreach(var groupMember in groupMembers)
            {
                <MudSelectItem T="int" Value = "@groupMember.MemberId">@groupMember.LastName @groupMember.FirstName</MudSelectItem>
            }
        </MudTd>

但问题是数据库中的所有群组成员都显示在所有群组中。 以下是整个群组页面:

@page "/EditGroups"
@using MMSProjectShared
@using System.Linq
@using System
@using static MudBlazor.CategoryTypes
@inject MMSProjectServer.Interfaces.ILoan LoanService
@inject MMSProjectServer.Interfaces.IGroup GroupService
@inject MMSProjectServer.Interfaces.IGroupMember GroupMemberService
@inject MMSProjectServer.Interfaces.ICategory CategoryService
@inject MudBlazor.ISnackbar snackBar


<MudCard Elevation="25">
    <MudCardHeader>
        <CardHeaderContent>
            <MudText Typo="Typo.h6">Add / Edit Groups</MudText>
        </CardHeaderContent>
    </MudCardHeader>
    <MudCardContent>
        <MudTextField @bind-Value="group.GroupName" Label="Name of Group" Variant="Variant.Text" Margin="Margin.Normal"></MudTextField>
        <MudTextField @bind-Value="group.Product_Service" Label="Product or Service" Variant="Variant.Text" Margin="Margin.Normal"></MudTextField>
        <MudSelect T="int" Label="Select Category" @bind-Value = "group.CategoryId">
            @foreach(var category in categories){
        <MudSelectItem T="int" Value = "@category.CategoryId">@category.CategoryName</MudSelectItem>
            }
        </MudSelect>
        
        <br />
        <MudButton Variant="Variant.Filled" Color="Color.Success" OnClick="Save">Save Group</MudButton>
    </MudCardContent>
</MudCard>
<br />
<MudTable Elevation="25" Items="GetGroups()" Filter="new Func<Group, bool>(Search)" @bind-customer="group">
    <ToolBarContent>
        <MudText Typo="Typo.h6">Groups</MudText>
        <MudSpacer />
        <MudTextField @bind-Value="searchString" Placeholder="Search for Groups..." Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
    </ToolBarContent>
    <HeaderContent>
        <MudTh>ID</MudTh>
        <MudTh>GroupName</MudTh>
        <MudTh>Product/Service</MudTh>
        <MudTh>GroupMembers</MudTh>
        <MudTh>Loan</MudTh>
        <MudTh>Category</MudTh>
        <MudTh>Action</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Id">@context.GroupId</MudTd>
        <MudTd DataLabel="Group Name">@context.GroupName</MudTd>
        <MudTd DataLabel="Product/Service">@context.Product_Service</MudTd>
        <MudTd DataLabel="GroupMembers">
            @foreach(var groupMember in groupMembers)
            {
                <MudSelectItem T="int" Value = "@groupMember.MemberId">@groupMember.LastName @groupMember.FirstName</MudSelectItem>
            }
        </MudTd>
        <MudTd DataLabel="Loans">
            
        </MudTd>
        <MudTd DataLabel="Categoty">@context.Category.CategoryName</MudTd>
        <MudTd DataLabel="">
            <MudFab @onclick="@(()=>Edit(@context.GroupId))" Color="Color.Primary" Icon="@Icons.Material.Filled.Edit" Size="Size.Small" IconSize="Size.Small" />
            <MudFab @onclick="@(()=>Delete(@context.GroupId))" Color="Color.Secondary" Icon="@Icons.Material.Filled.Delete" Size="Size.Small" IconSize="Size.Small" />
        </MudTd>
    </RowTemplate>
</MudTable>

@code{
    private string searchString = "";
    private Group group = new Group();
    private List<Group> groups = new List<Group>();
    //List of Categories for drop down list
    private Category category = new Category();
    private List<Category> categories = new List<Category>();
    //Because we want to view the loan number for each group's loans
    private Loan loan = new Loan();
    private List<Loan> loans = new List<Loan>();

    private GroupMember groupMember = new GroupMember();
    private List<GroupMember> groupMembers = new List<GroupMember>();

    protected override async Task OnInitializedAsync()
    {
        GetGroups();
        groupMembers = GroupMemberService.GetGroupMembers();
        loans = LoanService.GetLoans();
        categories = CategoryService.GetCategories();
    }

    private List<Group> GetGroups()
    {
        groups = GroupService.GetGroups();
        return groups;
    }

    //private List<GroupMember> GetGroupMembers()
    //{
    //    groupMembers = GroupMemberService.GetGroupMembers();
    //    return groupMembers;
    //}
    private bool Search(Group group)
    {
        if (string.IsNullOrWhiteSpace(searchString)) return true;
        if (group.GroupName.Contains(searchString, StringComparison.OrdinalIgnoreCase)
            || group.Product_Service.Contains(searchString, StringComparison.OrdinalIgnoreCase)
            || group.Category.CategoryName.Contains(searchString, StringComparison.OrdinalIgnoreCase))
        {
            return true;
        }
        return false;
    }
    private void Save()
    {
        GroupService.SaveGroup(group);
        group = new Group();
        snackBar.Add("Group Saved.", Severity.Success);
        GetGroups();
    }
    private void Edit(int id)
    {
        group = groups.FirstOrDefault(c => c.GroupId == id);
    }
    private void Delete(int id)
    {
        GroupService.DeleteGroup(id);
        snackBar.Add("Group Deleted.", Severity.Success);
        GetGroups();
    }
}

您可以将 groupMembers 设为字典而不是列表,然后将组成员存储在那里,按组 ID 分组。

示例:

//using System.Collections.Generic;

private Dictionary<int, GroupMember> groupMembersByGroupId;

假设 GroupMemberService.GetGroupMembers() returns 和 IEnumerable<GroupMember>,您的字典的填充可以按如下方式完成:

//using System.Linq;

groupMembersByGroupId = GroupMemberService.GetGroupMembers()
    .GroupBy(member => member.GroupId)
    .ToDictionary(gr => gr.Key, gr => gr.Select(member => member));

在您的 table 中,您可以按如下方式访问所需群组的群组成员:

@foreach(var groupMember in groupMembersByGroupId[context.GroupId])
{
    ...
}

注意:如果key(context.GroupId)在字典中不存在,groupMembersByGroupId[context.GroupId]会抛出异常;即如果该组不包含任何组成员。您可能希望将 foreach 循环包裹在 if 中,以确保确实有任何组成员要显示:

if (groupMembersByGroupId.ContainsKey(context.GroupId))
{
    @foreach(var groupMember in groupMembersByGroupId[context.GroupId])
    {
        ...
    }
}

示例 fiddle here.

您可以使用导航属性轻松实现这一目标。
在您的 GroupService class

public class GroupService: IGroup
{
   ...
   public List<Group> GetGroups()
   {
       return context.Groups.Include(g=>g.GroupMembers)
                            .Include(g=>g.Loans)
                            .Include(g=>g.Category).ToList();
   }
   ...
}

在你的剃须刀文件中

@page "/EditGroups"
@using MMSProjectShared
@using System.Linq
@using System
@using static MudBlazor.CategoryTypes
@inject MMSProjectServer.Interfaces.ILoan LoanService
@inject MMSProjectServer.Interfaces.IGroup GroupService
@inject MMSProjectServer.Interfaces.IGroupMember GroupMemberService
@inject MMSProjectServer.Interfaces.ICategory CategoryService
@inject MudBlazor.ISnackbar snackBar


<MudCard Elevation="25">
    <MudCardHeader>
        <CardHeaderContent>
            <MudText Typo="Typo.h6">Add / Edit Groups</MudText>
        </CardHeaderContent>
    </MudCardHeader>
    <MudCardContent>
        <MudTextField @bind-Value="group.GroupName" Label="Name of Group" Variant="Variant.Text" Margin="Margin.Normal"></MudTextField>
        <MudTextField @bind-Value="group.Product_Service" Label="Product or Service" Variant="Variant.Text" Margin="Margin.Normal"></MudTextField>
        <MudSelect T="int" Label="Select Category" @bind-Value = "group.CategoryId">
            @foreach(var category in categories){
        <MudSelectItem T="int" Value = "@category.CategoryId">@category.CategoryName</MudSelectItem>
            }
        </MudSelect>
        
        <br />
        <MudButton Variant="Variant.Filled" Color="Color.Success" OnClick="Save">Save Group</MudButton>
    </MudCardContent>
</MudCard>
<br />
<MudTable Elevation="25" Items="@groups" Filter="new Func<Group, bool>(Search)" @bind-customer="group">
    <ToolBarContent>
        <MudText Typo="Typo.h6">Groups</MudText>
        <MudSpacer />
        <MudTextField @bind-Value="searchString" Placeholder="Search for Groups..." Adornment="Adornment.Start" AdornmentIcon="@Icons.Material.Filled.Search" IconSize="Size.Medium" Class="mt-0"></MudTextField>
    </ToolBarContent>
    <HeaderContent>
        <MudTh>ID</MudTh>
        <MudTh>GroupName</MudTh>
        <MudTh>Product/Service</MudTh>
        <MudTh>GroupMembers</MudTh>
        <MudTh>Loan</MudTh>
        <MudTh>Category</MudTh>
        <MudTh>Action</MudTh>
    </HeaderContent>
    <RowTemplate>
        <MudTd DataLabel="Id">@context.GroupId</MudTd>
        <MudTd DataLabel="Group Name">@context.GroupName</MudTd>
        <MudTd DataLabel="Product/Service">@context.Product_Service</MudTd>
        <MudTd DataLabel="GroupMembers">
            @if(context.GroupMembers.Any()){
            foreach(var groupMember in context.GroupMembers)
            {
                <MudSelectItem T="int" Value = "@groupMember.MemberId">@groupMember.LastName @groupMember.FirstName</MudSelectItem>
            }
}
else
{
<MudAlert Severity="Severity.Info">No Group Members In this Group</MudAlert>
}
        </MudTd>
        <MudTd DataLabel="Loans">
            
        </MudTd>
        <MudTd DataLabel="Categoty">@context.Category.CategoryName</MudTd>
        <MudTd DataLabel="">
            <MudFab @onclick="@(()=>Edit(@context.GroupId))" Color="Color.Primary" Icon="@Icons.Material.Filled.Edit" Size="Size.Small" IconSize="Size.Small" />
            <MudFab @onclick="@(()=>Delete(@context.GroupId))" Color="Color.Secondary" Icon="@Icons.Material.Filled.Delete" Size="Size.Small" IconSize="Size.Small" />
        </MudTd>
    </RowTemplate>
</MudTable>

@code{
    private string searchString = "";
    private Group group = new Group();
    private List<Group> groups = new List<Group>();
    //List of Categories for drop down list
    private Category category = new Category();
    Loan loan = new Loan();
    private GroupMember groupMember = new GroupMember();
    protected override async Task OnInitializedAsync()
    {
       GetGroups();       
    }
   void GetGroups()
{
 groups = groupService.GetGroups();
StateHasChanged();
}
 
    private bool Search(Group group)
    {
        if (string.IsNullOrWhiteSpace(searchString)) return true;
        if (group.GroupName.Contains(searchString, StringComparison.OrdinalIgnoreCase)
            || group.Product_Service.Contains(searchString, StringComparison.OrdinalIgnoreCase)
            || group.Category.CategoryName.Contains(searchString, StringComparison.OrdinalIgnoreCase))
        {
            return true;
        }
        return false;
    }
    private void Save()
    {
        GroupService.SaveGroup(group);
        group = new Group();
        snackBar.Add("Group Saved.", Severity.Success);
        GetGroups();
    }
    private void Edit(int id)
    {
        group = groups.FirstOrDefault(c => c.GroupId == id);
    }
    private void Delete(int id)
    {
        GroupService.DeleteGroup(id);
        snackBar.Add("Group Deleted.", Severity.Success);
        GetGroups();
    }
}