Ядро Entity Framework: Включение данных поиска из представления SQL для отображения на странице Razor - PullRequest
0 голосов
/ 27 января 2020

Впервые в Entity Framework, и я пытаюсь включить данные из представления SQL, которое представляет собой список кодов и имен сайтов. В настоящее время я пытаюсь перечислить все Incident s, но отображаю имя сайта вместо кода сайта. Я начал с Incident.Site как int, но потом я не был уверен, как загрузить имя из этого.

Классы:

public class Incident
{
    public int Id { get; set; }
    public Site Site { get; set; }
    public string Title { get; set; }
    public string ReportedBy { get; set; }
}

public class Site
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Incident Incident { get; set; }
}

Контекст БД:

modelBuilder.Entity<Incident>(entity =>
{
    entity.ToTable("Incidents");

    entity.Property(e => e.Id)
        .HasColumnName("ID");

    // Obviously incorrect
    entity.HasOne(e => e.Site)
        .WithOne(s => s.Incident)
        .HasForeignKey<Site>(s => s.Id);

    entity.Property(e => e.Title)
        .IsRequired()
        .HasMaxLength(50);

    entity.Property(e => e.ReportedBy)
        .IsRequired()
        .HasMaxLength(255);
});

modelBuilder.Entity<Site>(entity =>
{
    entity.HasNoKey();
    entity.ToView("vw_Locations");
    entity.Property(e => e.Id).HasColumnName("Code");
});

SQL просмотр:

create view vw_Locations as
select Code, Name
from MyTable
where <some filters>

Razor .cs html .cs:

public async Task<IActionResult> OnGetAsync()
{
    Incidents = await _context.Incidents.ToListAsync();

    return Page();
}

Razor .cs html:

<table class="table table-sm table-striped">
    <thead>
        <tr>
            <th>@Html.DisplayNameFor(model => model.Incidents[0].Title)</th>
            <th>@Html.DisplayNameFor(model => model.Incidents[0].Site)</th>
            <th>@Html.DisplayNameFor(model => model.Incidents[0].ReportedBy)</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model.Incidents)
        {
            <tr>
                <td><a asp-page="./Incident" asp-route-id="@item.Id">@Html.DisplayFor(modelItem => item.Title)</a></td>
                <td>@Html.DisplayFor(modelItem => item.Site.Name)</td>
                <td>@Html.DisplayFor(modelItem => item.EnteredBy)</td>
            </tr>
        }
    </tbody>
</table>

При запуске страницы в этой строке кода возникает исключение:

Incidents = await _context.Incidents.ToListAsync();

Исключение:

InvalidOperationException: невозможно определить отношение, представленное свойством навигации «Incident.Site» типа «Сайт». Либо настройте отношение вручную, либо игнорируйте это свойство с помощью атрибута [NotMapped] или с помощью EntityTypeBuilder.Ignore в OnModelCreating.

Что мне не хватает?

Ответы [ 2 ]

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

Отношение определяет, как два реальных объекта связаны друг с другом. Они сопоставляются с соответствующими таблицами в базе данных и используют внешний ключ для создания отношений.

Попробуйте следующий код:

Модель

public class Incident
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string ReportedBy { get; set; }

    public int SiteId { get; set; }
    public Site Site{ get; set; }
}
public class Site
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Incident Incident { get; set; }
}

DbContext

public DbSet<Incident> Incidents { get; set; }
    public DbSet<Site> Sites { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Incident>(entity =>
        {
            entity.ToTable("Incidents");

            entity.Property(e => e.Id)
                .HasColumnName("ID");

            entity.Property(e => e.Title)
                .IsRequired()
                .HasMaxLength(50);

            entity.Property(e => e.ReportedBy)
                .IsRequired()
                .HasMaxLength(255);
        });

        modelBuilder.Entity<Site>(entity =>
        {
            //entity.HasNoKey();
            entity.ToTable("Location");
            entity.Property(e => e.Id).HasColumnName("Code");

            entity.HasOne(s => s.Incident)
                  .WithOne(i=>i.Site)
                  .HasForeignKey<Incident>(s => s.SiteId);
        });
    }

PageModel : используйте Include для загрузки связанных данных

public async Task<IActionResult> OnGetAsync()
{
        Incidents = await _context.Incidents.Include(i=>i.Site).ToListAsync();

        return Page();
}

Результат:

enter image description here

Для Keyless Типы сущностей и отношения, вы можете ссылаться на следующие ссылки:

https://docs.microsoft.com/en-us/ef/core/modeling/keyless-entity-types

https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key

0 голосов
/ 28 января 2020

Удалите приведенный ниже код:

// Obviously incorrect
entity.HasOne(e => e.Site)
.WithOne(s => s.Incident)
.HasForeignKey<Site>(s => s.Id);

Вы уже установили sh отношение один к одному между Сайтом и Инцидентом в следующем коде. Нет необходимости делать это дважды:

public class Incident
{
     public int Id { get; set; }
     public Site Site { get; set; }  //Relationship
     public string Title { get; set; }
     public string ReportedBy { get; set; }
}

public class Site
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Incident Incident { get; set; }  //Relationship
} 

Следующая ссылка является абсолютным лучшим базовым ресурсом фреймворка сущностей: https://www.learnentityframeworkcore.com/relationships Я использую его все время для справки.

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