EF Core 中的显式加载随机加载 .Include()

Explicit loading in EF Core randomly loads .Include()

我的 .NET 5 项目有 Index 页面,其中 table 包含来自 table Contracts 的所有行,每行有 Contract_StatusID 列,其中从 table Contract_Statuses 中保存 FK - table Contracts 有更多具有此逻辑的列

事实是,显式加载仅完全加载 table 的最后一行,其他行的列是随机的 null,即使收集是来自控制器代码的 .Include(s => s.Contract_Status)。 所有 ID 列都已设置,这些 ID 存在于相关 table 中,但未加载到 Index 页面上的此 table 中。

Detail 页面始终正确加载所有 .Include() 关系 table,但不在 Index 页面上。

我已经验证了我的模型,它们看起来不错,并且可以在网站的其他页面中工作。

我错过了什么?已经为此浏览了 MSDN 和 EFCore 教程,但它就是行不通。

public async Task<IActionResult> Index()
{
    var contract = await context.Contracts
        .Include(c => c.Employee)
            .ThenInclude(c => c.Gender)
        .Include(i => i.Business_Unit)
        .Include(i => i.Brand)
        .Include(i => i.Contract_Status)
        .Include(i => i.Statutory_Unit)
        .Include(i => i.Management_Market).ToListAsync();
    return View(contract);
}

编辑:添加我的 Index.cshtml

@model IEnumerable<MyProject.Models.Contract>    
<table class="table table-hover">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Employee)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Contract_Status.Contract_Status)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Business_Unit.Business_Unit)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Brand.Brand)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Statutory_Unit.Statutory_Unit)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Management_Market.Management_Market)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Employee.EmployeeID)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Contract_Status.Contract_Status)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Business_Unit.Business_Unit)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Brand.Brand)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Statutory_Unit.Statutory_Unit)
                </td>
                <td>
                    @Html.DisplayFor(modelItem => item.Management_Market.Management_Market)
                </td>
                <td>
                    <a asp-action="Edit" asp-route-id="@item.ContractID">Edit</a> |
                    <a asp-action="Details" asp-route-id="@item.ContractID">Details</a>
                </td>
            </tr>
            }
        </tbody>
    </table>

和我的 Contract 模型以及相关的示例 table

    public class Contract
    {
        [Key]
        [Required]
        public Guid ContractID { get; set; }

        [Required]
        public string EmployeeID { get; set; }
        public Employee Employee { get; set; }

        [Required]
        public int Contract_StatusID { get; set; }
        public CONF_Contract_Status Contract_Status { get; set; }

        [Required]
        public int Business_UnitID { get; set; }
        public CONF_Business_Unit Business_Unit { get; set; }

        [Required]
        public int BrandID { get; set; }
        public CONF_Brand Brand { get; set; }

        [Required]
        public int Statutory_UnitID { get; set; }
        public CONF_Statutory_Unit Statutory_Unit { get; set; }


        [Required]
        public int Management_MarketID { get; set; }
        public CONF_Management_Market Management_Market { get; set; }
    }

public class CONF_Contract_Status
{
    [Key]
    public int CS_ID { get; set; }

    [Required]
    [Display(Name = "Status")]
    public string Contract_Status { get; set; }

    [Required]
    public bool Enabled { get; set; }

    public Contract Contract { get; set; }
}

Contracttable 的数据库截图

CONF_Contract_Status

我通常总是为索引视图创建视图模型,因为它通常需要几个字符串列,但它可以有很多列。如果你只需要一列,你不需要从服务器获取整个记录


 public class ContractVieModel
    {
        public Guid ContractID { get; set; }

        public string EmployeeName { get; set; }
        public  string Contract_Status { get; set; }
        public string Business_Unit { get; set; }
        
      .... and so on
    }

动作,你不要显式使用Include

public async Task<IActionResult> Index()
{
    var model = await context.Contracts
    .Select(i=> new ContractViewModel
     {
       Id=i.Id,
       EmployeeName=i.Employee.Name
      Contract_Status =i.Contract_Status.Contract_Status,
      Business_Unit = i.Business_Unit.Business_Unit,
      ... and so on 
      }).ToListAsync();

    return View(model);
}

查看

@model IEnumerable<ContractViewModel> 

......

尝试一下,如果它仍然不起作用,那么您将不得不使用左外连接来获取视图模型