簡體   English   中英

如何在 Entity Framework 6.4 上使用 Linq 獲取多對多關系記錄?

[英]How can I get many to many relationship records with using Linq on Entity Framework 6.4?

我有一個數據庫,我在下面給出了詳細信息。

有項目,也有與項目相關的模塊和版本。 雖然,每個版本都不包含每個模塊。

如何在 Entity Framework 6.4 上使用 Linq 獲取這些記錄?

這是我想要得到的 JSON 結果。

{
  "id": 1,
  "name": "Super Project",
  "versions": [
    {
      "id": 1,
      "name": "Basic",
      "availableModules": []
    },
    {
      "id": 2,
      "name": "Advenced",
      "availableModules": [
        {
          "id": 1,
          "name": "3 Users"
        },
        {
          "id": 2,
          "name": "50Gb Space"
        }
      ]
    }
    ....
    ....
    
  ]
}

這是數據庫查詢:

SELECT 
    p.Id ProjectID, p.Name ProjectName, pv.Name VersionName, 
    pm.Name ModuleName
FROM
    Project p
INNER JOIN
    ProjectVersion pv ON pv.ProjectId = p.Id
LEFT JOIN 
    ProjectModuleAvailableVersions mav ON mav.ProjectVersionId = pv.Id
LEFT JOIN
    ProjectModule pm ON pm.ID = mav.ProjectModuleId

該查詢的結果截圖如下:

在此處輸入圖像描述

如果您想嘗試,有數據庫結構:

IF OBJECT_ID('ProjectModuleAvailableVersions') IS NOT NULL 
     DROP TABLE ProjectModuleAvailableVersions

IF OBJECT_ID('ProjectModule') IS NOT NULL 
     DROP TABLE ProjectModule

IF OBJECT_ID('ProjectVersion') IS NOT NULL 
     DROP TABLE ProjectVersion

IF OBJECT_ID('Project') IS NOT NULL 
     DROP TABLE Project


CREATE TABLE dbo.Project
(
    Id INT IDENTITY(1,1) NOT NULL,
    Name VarChar(100) NULL,
    CONSTRAINT PK_Project PRIMARY KEY CLUSTERED (Id)
)
GO

CREATE TABLE dbo.ProjectVersion
(
    Id INT IDENTITY(1,1) NOT NULL,
    ProjectId INT,
    Name Varchar(100) NULL,
    CONSTRAINT PK_ProjectVersion PRIMARY KEY CLUSTERED (Id),
    CONSTRAINT FK_ProjectVersion_ProjectId 
        FOREIGN KEY (ProjectId) REFERENCES Project (Id) 
            ON DELETE CASCADE
)
GO

CREATE TABLE dbo.ProjectModule
(
    Id INT IDENTITY(1,1) NOT NULL,
    ProjectId INT,
    Name Varchar(100) NULL,
    CONSTRAINT PK_ProjectModule PRIMARY KEY CLUSTERED (Id),
    CONSTRAINT FK_ProjectModule_ProjectId 
        FOREIGN KEY (ProjectId) REFERENCES Project (Id) 
            ON DELETE CASCADE
)
GO

CREATE TABLE dbo.ProjectModuleAvailableVersions
(
    Id INT IDENTITY(1,1) NOT NULL,
    ProjectVersionId INT,
    ProjectModuleId INT,
    CONSTRAINT PK_ProjectModuleAvailableVersions PRIMARY KEY CLUSTERED (Id)
)
GO

INSERT INTO Project Values ('Super Project')           -- ID: 1
INSERT INTO Project Values ('Fantastic Project')       -- ID: 2

INSERT INTO ProjectVersion Values (1, 'Basic')         -- ID: 1
INSERT INTO ProjectVersion Values (1, 'Advanced')      -- ID: 2
INSERT INTO ProjectVersion Values (2, 'Modern')        -- ID: 3
INSERT INTO ProjectVersion Values (2, 'Professional')  -- ID: 4
INSERT INTO ProjectVersion Values (2, 'Cloud')         -- ID: 5 

INSERT INTO ProjectModule Values (1, '3 Users')        -- ID: 1
INSERT INTO ProjectModule Values (1, '50Gb Space')     -- ID: 2
INSERT INTO ProjectModule Values (2, 'SyncData')       -- ID: 3 
INSERT INTO ProjectModule Values (2, 'Export Data')    -- ID: 4
INSERT INTO ProjectModule Values (2, 'Import Data')    -- ID: 5

INSERT INTO ProjectModuleAvailableVersions Values (2,1)  -- Advanced - 3 Users
INSERT INTO ProjectModuleAvailableVersions Values (2,2)  -- Advanced - 50Gb
INSERT INTO ProjectModuleAvailableVersions Values (3,3)  -- Modern - SynData
INSERT INTO ProjectModuleAvailableVersions Values (4,3)  -- Professional - SyncData
INSERT INTO ProjectModuleAvailableVersions Values (4,4)  -- Professional - ExprotData
INSERT INTO ProjectModuleAvailableVersions Values (5,3)  -- Professional - SyncData
INSERT INTO ProjectModuleAvailableVersions Values (5,4)  -- Professional - ExprotData
INSERT INTO ProjectModuleAvailableVersions Values (5,5)  -- Professional - ImportData

編輯:我的課在這里

public class ProjectDto : IDto
{
  public int Id { get; set; }
  public string? Name { get; set; }
  public List<ProjectVersionDto>? Versions { get; set; }
}

public class ProjectVersionDto : IDto
{
  public int Id { get; set; }
  public string? Name { get; set; }
  public List<ProjectModuleDto> Modules { get; set; }
}

public class ProjectModuleDto : IDto
{
  public int ID { get; set; }
  public string? Name { get; set; }
}

我就是這樣做的。

using CrmContext context = new CrmContext();
var result = from p in context.Project
    select new ProjectDto()
    {
        Id = p.ID,
        Name = p.Name,
        Versions = (from pv in context.ProjectVesion
            where pv.Project == p.ID
            join av in context.ProjectModuleAvailableVersions on pv.ID equals av.Version
            select new ProjectVersionDto
            {
            Modules = (from pm in context.ProjectModule
                        where pm.Project == p.ID
                        join an in context.ProjectModuleAvailableVersions on pv.ID equals an.Version
                        select new ProjectModuleDto
                        {
                        ID = 0,
                        Name = null,
                        }
                ).ToList()
            }).ToList()
    };
return result.ToList();

在我看來,您的問題與加入操作有關。

var result = from p in context.Project
select new ProjectDto()
{
    Id = p.Id,
    Name = p.Name,
    Versions = (from pv in context.ProjectVesion.OrderBy(o => o.ProjectId)
        where p.Id == pv.ProjectId
        select new ProjectVersionDto
        {
        Id = pv.Id,
        Name = pv.Name,
        Modules = (from pm in context.ProjectModule
            where pm.ProjectId == pv.ProjectId
            join pav in context.ProjectModuleAvailableVersions on pm.Id equals pav.ModuleId
            where pav.VersionId == pv.Id
            select new ProjectModuleDto
            {
            Id = pm.Id,
            Name = pm.Name,
            }).ToList()
        }).ToList()
};
  return result.ToList();

嵌套對象的順序如下;

ProjectDto > 版本 > 模塊

如果您不對ProjectModuleAvailableVersions表進行左連接,則不會有任何問題。

祝你今天過得愉快。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM