简体   繁体   English

如何在同一个表上创建数据或实体关系并在第一个连接表上连接另一个表?

[英]How to Create Data or Entity Relationship on the same Table and Join another Table on the first Joined Table?

I'm having a problem building data or entity relationships with the same table and joining another table to the first inner joined table.我在使用同一个表构建数据或实体关系并将另一个表连接到第一个内部连接表时遇到问题。

I want to get the query result this way:我想以这种方式获取查询结果:

SELECT [n].[ISCInstanceId], [n].[NavPointId], [n].[ParentNPId], [n].[DataPointId], [n].[NodeOrder], [n].[RefNumber], [n].[TreeTitle], [n].[IsArchived], [n].[IsInNavbar], [i].[Name]
  FROM [NavPoints] AS [n]
  INNER JOIN [NavPoints] AS [n0] ON [n].[ParentNPId] = [n0].[NavPointId]
  INNER JOIN [ISCInstances] AS [i] ON [n0].[ISCInstanceId] = [i].[ISCInstanceId]
  WHERE (([n].[IsArchived] = CAST(0 AS bit)) AND ([n].[IsInNavbar] = CAST(1 AS bit))) AND ([n0].[ISCInstanceId] = @__IscinstanceId_0)
  ORDER BY [n].[ParentNPId], [n].[NodeOrder]

but I'm getting this:但我得到了这个:

SELECT [n].[ISCInstanceId], [n].[NavPointId], [n].[ParentNPId], [n].[DataPointId], [n].[NodeOrder], [n].[RefNumber], [n].[TreeTitle], [n].[IsArchived], [n].[IsInNavbar], [i].[Name]
  FROM [NavPoints] AS [n]
  INNER JOIN [NavPoints] AS [n0] ON [n].[ParentNPId] = [n0].[NavPointId]
  INNER JOIN [ISCInstances] AS [i] ON [n].[ISCInstanceId] = [i].[ISCInstanceId]
  WHERE (([n].[IsArchived] = CAST(0 AS bit)) AND ([n].[IsInNavbar] = CAST(1 AS bit))) AND ([n0].[ISCInstanceId] = @__IscinstanceId_0)
  ORDER BY [n].[ParentNPId], [n].[NodeOrder]

The problem is that section or line INNER JOIN [ISCInstances] AS [i] ON [n].[ISCInstanceId] = [i].[ISCInstanceId] witch is the query I'm getting is not joining to the first inner joined table, I want it to be like this INNER JOIN [ISCInstances] AS [i] ON [n0].[ISCInstanceId] = [i].[ISCInstanceId]问题是部分或行INNER JOIN [ISCInstances] AS [i] ON [n].[ISCInstanceId] = [i].[ISCInstanceId]女巫是我得到的查询没有加入第一个内部连接表,我希望它像这样INNER JOIN [ISCInstances] AS [i] ON [n0].[ISCInstanceId] = [i].[ISCInstanceId]

DB Context数据库上下文

modelBuilder.Entity<NavPoint>(entity =>
{
    ...
    entity.HasOne(d => d.Iscinstances)
        .WithMany(p => p.NavPoints)
        .HasForeignKey(d => d.IscinstanceId)
        .OnDelete(DeleteBehavior.ClientSetNull)
        .HasConstraintName("FK_NavPoints_Iscinstances");

    entity.HasOne(d => d.NavPointsParent)
        .WithMany(p => p.NavPoints)
        .HasForeignKey(d => d.ParentNpid)
        .OnDelete(DeleteBehavior.ClientSetNull)
        .HasConstraintName("FK_NavPoints_NavPoints");
});

Class Model类模型

// <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated>
#nullable disable
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace Odysseus_API.Models
{
    public partial class NavPoint
    {
        public NavPoint()
        {
            NavPoints = new HashSet<NavPoint>();
        }
        [key]
        public int NavPointId { get; set; }
        public int ParentNpid { get; set; }
        ...
        [ForeignKey("ParentNpid")]
        public virtual NavPoint NavPointsParent { get; set; }
        public virtual Iscinstance Iscinstances { get; set; }
        [ForeignKey("NavPointId")]
        public virtual ICollection<NavPoint> NavPoints { get; set; }
    }
}

Controller控制器

[HttpGet]
public async Task<ActionResult<NavPoint>> GetNavPoint(int IscinstanceId)
{
    if (_context.Users == null)
    {
        return NotFound();
    }

    var navpoint = await _context.NavPoints
               .Where(c => c.IsArchived == false  && c.IsInNavbar == true && c.NavPointsParent.IscinstanceId == IscinstanceId)
               .Include(c => c.NavPointsParent).Include(c => c.Iscinstances)
               .OrderBy(c => c.ParentNpid).ThenBy(c => c.NodeOrder)
               .Select(c => new NavPoint
               {
                   ...
               })
               .ToListAsync();

    if (navpoint == null)
    {
        return NotFound();
    }

    return Ok(navpoint);
}

Basically what you have is:基本上你所拥有的是:

var navpoint = await _context.NavPoints
    .Include(c => c.NavPointsParent)
    .Include(c => c.Iscinstances)

Include always applies to the root of the query, so you include the Iscinstances of _context.NavPoints . Include始终适用于查询的根,因此您包含_context.NavPoints Iscinstances This would have the same effect:这将具有相同的效果:

var navpoint = await _context.NavPoints
    .Include(c => c.Iscinstances)
    .Include(c => c.NavPointsParent)

To Include the Iscinstances of NavPointsParent , use:Include IscinstancesNavPointsParent ,请使用:

var navpoint = await _context.NavPoints
    .Include(c => c.NavPointsParent)
        .ThenInclude(c => c.Iscinstances)

ThenInclude expands a previous Include . ThenInclude扩展了先前的Include

After your comments: the point here is that you need the navigation property c.NavPointsParent.Iscinstance , even when not using Include .在您发表评论之后:这里的重点是您需要导航属性c.NavPointsParent.Iscinstance ,即使不使用Include也是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM