Связанные с ядром .net выглядят иначе, чем стандартный asp.net mvc для дочерних записей? - PullRequest
0 голосов
/ 01 июня 2018

В одном из моих представлений у меня есть серия дочерних таблиц, где у дочерней таблицы есть связанный поиск, т.е. не таблица внука.Связанный поиск - это описание кода.В стандартном asp.net mvc я могу указать на эту связанную таблицу и отобразить описание в этой дочерней записи.В ядре .net оно выглядит пустым.Если я просто отображаю код в дочерних записях, он работает.

Я что-то упустил?Код для модели, контроллера и вида ниже:

Традиционный mvc asp.net, который работает: Модель

Model

namespace ServeMeHR.Models
{
    using System;
    using System.Collections.Generic;

    public partial class TeamAssignmentHistory
    {
        public int Id { get; set; }
        public string AssignedBy { get; set; }
        public System.DateTime DateAssigned { get; set; }
        public int ServiceRequest { get; set; }
        public int Team { get; set; }

        public virtual ServiceRequest ServiceRequest1 { get; set; }
        public virtual Team Team1 { get; set; }
    }
}

Соответствующая часть контроллера

public async Task<ActionResult> Details(int? id)
    {
        ViewBag.FileUp = db.ApplicConfs.Select(s => s.FileSystemUpload).FirstOrDefault();

        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        ServiceRequest serviceRequest = await db.ServiceRequests.FindAsync(id);
        if (serviceRequest == null)
        {
            return HttpNotFound();
        }
        return View(serviceRequest);
    }

Соответствующая часть просмотра

<div id="tabs-2">
            <table class="table">
                <tr>
                    <th>Assigned BY</th>
                    <th>Date Assigned</th>
                    <th>Team</th>
                </tr>
                @foreach (var item in Model.TeamAssignmentHistories)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.AssignedBy)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.DateAssigned)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Team1.TeamDescription)
                        </td>
                    </tr>
                }
            </table>
        </div>

Для .Net Core -Это не работает

Модель

    using System;
using System.Collections.Generic;

namespace ServeMeHRCore21.Models
{
    public partial class TeamAssignmentHistories
    {
        public int Id { get; set; }
        public string AssignedBy { get; set; }
        public DateTime DateAssigned { get; set; }
        public int ServiceRequest { get; set; }
        public int Team { get; set; }

        public ServiceRequests ServiceRequestNavigation { get; set; }
        public Teams TeamNavigation { get; set; }
    }
}

соответствующий код контроллера

Relevant part of controller



// GET: ServiceRequests/Details/5
    public async Task<IActionResult> Details(int? id)
    {
        if (id == null)
        {
            return NotFound();
        }

        var serviceRequests = await _context.ServiceRequests
            .Include(s => s.MemberNavigation)
            .Include(s => s.PriorityNavigation)
            .Include(s => s.RequestTypeNavigation)
            .Include(s => s.RequestTypeStepNavigation)
            .Include(s => s.StatusNavigation)
            .Include(s => s.TeamNavigation)
            .Include(s => s.FileDetails)
            .Include(s => s.ServiceRequestNotes)
            .Include(s => s.StepHistories)
            .Include(s => s.TeamAssignmentHistories)
            .Include(s => s.IndividualAssignmentHistories)
            .AsNoTracking()
            .SingleOrDefaultAsync(m => m.Id == id);
        if (serviceRequests == null)
        {
            return NotFound();
        }

        return View(serviceRequests);
    }

Соответствующая часть вида

<div id="tabs-2">
            <table class="table">
                <tr>
                    <th>Assigned BY</th>
                    <th>Date Assigned</th>
                    <th>Team</th>
                </tr>
                @foreach (var item in Model.TeamAssignmentHistories)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.AssignedBy)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.DateAssigned)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.TeamNavigation.TeamDescription)
                        </td>
                    </tr>
                }
            </table>
        </div>

Приведенный выше вид пуст для описания команды.Код для каждого из них практически идентичен ...

1 Ответ

0 голосов
/ 01 июня 2018

В зависимости от используемой версии EF Core, существуют различные решения.В EF 6 (то, что вы используете в ASP.NET MVC), ссылки / свойства коллекции с ключевым словом virtual участвуют в отложенной загрузке.EF динамически создает подклассы вашего класса сущностей, переопределяя свойства ссылки / коллекции (именно поэтому необходимо virtual) и добавляет логику для запроса базы данных при попадании в получатель.Затем, когда вы обращаетесь к этому свойству в своем приложении, если отношение недоступно, EF прозрачно запрашивает его и заполняет его, давая видимость, что оно всегда установлено и готово к работе.

До EF Core 2.1ленивая загрузка не была вариантом вообще.Чтобы эти свойства имели значения, вам нужно либо их явно, либо явно загрузить:

Стремительная загрузка

var foo = await _context.Foos.Include(x => x.Bar).SingleOrDefaultAsync(x => x.Id == fooId);

Явная загрузка

var foo = await _context.Foos.SingleOrDefaultAsync(x => x.Id == fooId);
await _context.Entry(foo).Reference(x => x.Bar).LoadAsync();
// use `Collection` rather than `Reference` for a collection type

EF Core 2.1 теперь поддерживает отложенную загрузку, но вам все еще нужно ключевое слово virtual, которого у вас в данный момент нет в свойствах ссылок / коллекций классов сущностей.Кроме того, вам нужно добавить соответствующие сервисы в Startup.cs:

services.AddDbContext<MyContext>(
    b => b.UseLazyLoadingProxies()
          .UseSqlServer(myConnectionString));

Однако я бы посоветовал вам не идти по этому пути, тем более что вы, кажется, не знаете, что какой-либо изто, что я упомянул, на самом деле происходило изнутри в EF 6. С ленивой загрузкой очень легко создавать всевозможные проблемы, такие как запросы N + 1, которые могут вызвать серьезные проблемы для вашего приложения.Почти всегда лучше загружать любые связанные объекты, чтобы вы могли комбинировать запросы.То, что EF Core теперь поддерживает отложенную загрузку, не означает, что вам нужно его использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...