【问题标题】:MVC Core: Display another property based on primary keyMVC Core:基于主键显示另一个属性
【发布时间】:2017-10-01 11:05:38
【问题描述】:

我有一个带有另一个表的外键的模型。在这种情况下,弃权对象与办公对象相关

public class Waiver
    {
        public int WaiverID { get; set; }
        [Required(ErrorMessage = "Please select an Office")]
        [Range(1, int.MaxValue, ErrorMessage = "Please select an Office")]
        public int OfficeID { get; set; }
        //...other properties
}

我有一个按 OfficeID 过滤的搜索结果:

 IEnumerable<Waiver> waiverList = repository.Waivers
                .Where(wl => waiverNum == 0 || wl.WaiverID == waiverNum)
                .Where(wl => officeId == 0 || wl.OfficeID == officeId)
//...other search criteria

这显示在我的视图中:

@model IEnumerable<Waiver>

@foreach (var item in Model)
    {
        <tr>
            <td class="text-right">@item.WaiverID</td>
            <td class="text-right">@item.OfficeID></td>
@* other display columns *@

虽然传递给 View 的 Waiver 对象具有 OfficeID 属性,但我想在 Office 模型中显示 Name 属性,因为它对用户更有用。我怎样才能做到这一点?

我的 EF 存储库设置为:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Waiver.Models

//This class implements the IWaiverRepository and gets its data using Entity Framework Core
{
    public class EFWaiverRepository : IWaiverRepository
    {


        private ApplicationDbContext context;

        public EFWaiverRepository(ApplicationDbContext ctx)
        {
            context = ctx;
        }


        public IEnumerable<Waiver> Waivers => context.Waivers;
        public IEnumerable<Office> Offices => context.Offices;

        //*****Waiver Methods*****
        public void SaveWaiver(Waiver waiver)
        {
            //if the waiver number is 0, create a new waiver
            if (waiver.WaiverID == 0)
            {
                context.Waivers.Add(waiver);
            }
            //if there wavier number exists, save the changes to the database
            else {
                Waiver dbEntry = context.Waivers.FirstOrDefault(w => w.WaiverID == waiver.WaiverID);
                if (dbEntry != null)
                {
                    dbEntry.Requestor = waiver.Requestor;
                    dbEntry.RequestorEmail = waiver.RequestorEmail;
                    dbEntry.OfficeID = waiver.OfficeID;
                    dbEntry.RequestDate = waiver.RequestDate;
                    dbEntry.System = waiver.System;
                    dbEntry.Source = waiver.Source;
                    dbEntry.Requirement = waiver.Requirement;
                    dbEntry.MitigationPlan = waiver.MitigationPlan;
                    dbEntry.FinalAssessment = waiver.FinalAssessment;
                    dbEntry.Status = waiver.Status;
                    //get the signatures
                    dbEntry.PmSignature = waiver.PmSignature;
                    dbEntry.PmSignDate = waiver.PmSignDate;
                }
            }
            context.SaveChanges();
        }

        public Waiver DeleteWaiver(int waiverID)
        {
            Waiver dbEntry = context.Waivers
                .FirstOrDefault(w => w.WaiverID == waiverID);
            if (dbEntry != null)
            {
                context.Waivers.Remove(dbEntry);
                context.SaveChanges();
            }
            return dbEntry;
        }

        //*****Office Methods*****
        public void SaveOffice(Office office)
        {
            //if the ID=0, its a new entry. Add to db
            if (office.OfficeID == 0)
            {
                context.Offices.Add(office);
            } else
            {
                Office dbEntry = context.Offices.FirstOrDefault(o => o.OfficeID == office.OfficeID);
                if (dbEntry != null)
                {
                    dbEntry.Name = office.Name;
                    dbEntry.SiteID = office.SiteID;
                }
            }
            context.SaveChanges();
        }

        public Office DeleteOffice(int officeID)
        {
            Office dbEntry = context.Offices
                .FirstOrDefault(o => o.OfficeID == officeID);
            if (dbEntry != null)
            {
                context.Offices.Remove(dbEntry);
                context.SaveChanges();
            }
            return dbEntry;
        }

EFRepository 实现的地方:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Waiver.Models
{
    public interface IWaiverRepository
    {
        IEnumerable<Waiver> Waivers { get; }
        IEnumerable<Office> Offices { get; }
        IEnumerable<Site> Sites { get; } 

        void SaveWaiver(Waiver waiver );
        Waiver DeleteWaiver(int waiverID);

        void SaveOffice(Office office);
        Office DeleteOffice(int officeID);
    }
}

【问题讨论】:

  • 您使用的是实体框架核心吗?这是什么版本?

标签: asp.net asp.net-mvc asp.net-core-mvc


【解决方案1】:

EF Core 尚无法进行延迟加载,因此您需要包含相关实体。解决方案应如下所示。

public class Waiver
{
    public int WaiverID { get; set; }
    [Required(ErrorMessage = "Please select an Office")]
    [Range(1, int.MaxValue, ErrorMessage = "Please select an Office")]
    public int OfficeID { get; set; }

    public virtual Office Office { set;get;}
}

repository.Waivers 需要更改如下。

更新

IEnumerable<Waiver> waiverList = repository.Waivers.Where(wl => waiverNum == 0 || wl.WaiverID == waiverNum).Where(wl => officeId == 0 || wl.OfficeID == officeId)

//...其他搜索条件

@model IEnumerable<Waiver>
<table>
@foreach (var item in Model)
{
    <tr>
        <td> @item.WaiverID </td>
        <td> @item.OfficeID </td>
        <td> @item.Office.Name </td>
    </tr>
}
</table>

更新

public IEnumerable&lt;Waiver&gt; Waivers =&gt; context.Waivers;更改为

public IEnumerable<Waiver> Waivers => context.Waivers.Include(o => o.Office);

如果这不起作用,您需要检查您的数据库上下文类并正确设置模型绑定内WaiversOffice 表之间的映射。

希望这会有所帮助。

【讨论】:

  • 这是有道理的,但我在“包含”方法上收到错误,因为它无法识别。这是在更新的 EF 中吗?我正在使用 1.1.1,但尝试更新到 EFCore 2.0.0 时出现错误
  • 不,这应该适用于您的版本,查看这篇官方文章。 docs.microsoft.com/en-us/ef/core/querying/related-data。只需要这两个参考。使用 Microsoft.EntityFrameworkCore;并使用 System.Linq;
  • 我认为您正在使用存储库模式,因此您需要更改存储库以在检索数据时支持包含功能。
  • 我是 MVC 核心的新手;我环顾四周,发现了一些关于该主题的信息,但我并不清楚如何在 EF 中实现 Include() 方法。
  • 您能否发布您的存储库代码,我会看看如何提供帮助。
【解决方案2】:

Office 类型的 Waiver 类中添加 virtual 导航属性。

public class Waiver
{
    public int WaiverID { get; set; }
    [Required(ErrorMessage = "Please select an Office")]
    [Range(1, int.MaxValue, ErrorMessage = "Please select an Office")]
    public int OfficeID { get; set; }

    public virtual Office Office { set;get;}
}

现在在您看来,您可以访问每个豁免项目的 Office 属性

@model IEnumerable<Waiver>
<table>
@foreach (var item in Model)
{
    <tr>
        <td> @item.WaiverID </td>
        <td> @item.OfficeID </td>
        <td> @item.Office.Name </td>
    </tr>
}
</table>

EF 将为您的豁免项目加载 Office 属性。

【讨论】:

    猜你喜欢
    • 2021-11-14
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 2016-07-21
    • 1970-01-01
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多