Получить значение IEnumerable без необходимости его жесткого кодирования

#entity-framework #entity-framework-core #entity-framework-5

#сущность-фреймворк #сущность-структура-ядро #entity-framework-5

Вопрос:

Я экспериментирую с добавлением страницы Razor, на которой будут отображаться сотрудники во всех магазинах, принадлежащих к одному и тому же идентификатору подгруппы компаний. Если я жестко закодирую значение .Contains("ABC") var employees , я получу список людей в этой компании и ее подгруппах. Если я попытаюсь использовать var currentEmpSub , я не получу свой список. Я не уверен, что мне нужно сделать (добавить еще одну переменную? исправить мой запрос LINQ? или что-то еще). Любые предложения были бы очень полезны! Как только я получу это, я также сделаю это для представления менеджера, в котором будут отображаться только сотрудники в хранилище менеджеров (вместо подгруппы).

Настройка — это отношение «многие ко многим» с EFCore 5.0

 public class Employee
{
public int Id {get; set;}
public string Name {get; set;]

public ICollection<Tenant> Tenants {get; set;}
}

public class Tenant
{
public int Id {get; set;}
public string Name {get; set;]

public ICollection<Employee> Employees{get; set;}
}

 

Admin.cs

 public async Task<IEnumerable<Employee>> GetAllEmployees()
        {
            var currentEmp = _httpContextAccessor.HttpContext?.User.GetUserId();
            
            var currentEmpTenant = await _context.Employees
                .Include(x => x.Tenants)
                .Where(e => e.AspUserId == currentEmp)
                .FirstAsync();

            var currentEmpSub = currentEmpTenant.Tenants
                .Select(x => x.SubName)
                .ToString();
            
            var employees = _context.Employees
                .IgnoreQueryFilters()
                .Include(t => t.Tenants)
                .Where(x => x.Tenants
                    .Select(sub => sub.SubName)
                    .Contains(currentEmpSub))
                .ToListAsync();
            return await employees;
        }
 

Index.cshtml

 @page
@using Navrae.DataLayer.Extensions
@model Navrae.WebApp.Pages.Admin.IndexModel
@{
}
<h2>Employee List</h2>
<table class="table-hover">
    <thead>
        <tr>
            <th>Employee Name</th>
            <th>Store</th>
        </tr>
    </thead>
    <tbody>
    @foreach (var emp in @Model.Employees)
    {
        <tr>
            <td>@emp.FullName</td>
            <td>
                @foreach (var comp in emp.Tenants)
                {
                    if (emp.Tenants.Count > 1)
                    {
                        String.Join(", ", @comp.CompanyName);
                    }
                    else
                    {
                        @comp.CompanyName
                    }
                }
            </td>
        </tr>
    }
    </tbody>
</table>
 

Index.cshtml.cs

 public class IndexModel : PageModel
    {
        private readonly IAdminView _adminView;

        public IndexModel(IAdminView adminView)
        {
            _adminView = adminView;
        }

        public IEnumerable<Employee> Employees { get; set; }

        public async Task OnGetAsync()
        {
            Employees = await _adminView.GetAllEmployees();
        }
    }
 

Комментарии:

1. Вы смотрели на содержимое currentEmpSub переменной? Потому что вызов String after Select(x => x.SubName) , скорее всего, приводит к чему-то вроде «List<string>», а не к значениям, которые вы пытаетесь туда поместить.

2. Вы правы, он действительно создал список<string> . Я заменил его . toString() с вызовом for . SingleOrDefault() и теперь это работает.

Ответ №1:

Пользователь @Ivan Stoev указал на это , позвонив .Функция toString() создала список. Хотя это не решило мою проблему, это был непреднамеренный побочный эффект. Я использовала .SingleOrDefault() в конце currentEmpSub и получил результат, который я искал.

** Примечание, которое вы также можете использовать .Single() .First() .FirstOrDefault()

 var currentEmpSub = currentEmpTenant.Tenants
                .Select(x => x.SubName)
                .SingleOrDefault();
``