简体   繁体   English

SQL查询到LINQ联接5个表

[英]SQL query to LINQ to join 5 tables

I have five tables which I am trying to get results from. 我有五个试图从中获得结果的表。 Below are my table designs. 下面是我的桌子设计。

Application and Environment tables: 应用程序和环境表:

Id, Name

NOTE - BOTH above tables have same properties. 注意-上面的两个表都具有相同的属性。

ResourceGroup table: ResourceGroup表:

Id, Name, Application_Id

ResourceGroupEnvironment table: ResourceGroupEnvironment表:

Id, ResourceGroup_Id, Environment_Id, VIP, URL

Servers table: 服务器表:

Id, ServerName, Alias, IPAddress, Network

ServerResourceGroup table: ServerResourceGroup表:

Id, Server_Id, ResourceGroup_Id, Environment_Id

What results I am trying to get? 我想要得到什么结果?

Based on above table design, I am expecting to get all servers that are part of ResourceGroup and Application table. 基于上述表设计,我希望获得属于ResourceGroupApplication表的所​​有服务器。 ResourceGroupEnvironment and ServerResourceGroup table shares environment table where ResourceGroupEnvironment will have one common environment, but ServerResourceGroup can have multiple servers in that environment. ResourceGroupEnvironmentServerResourceGroup表共享environment表,其中ResourceGroupEnvironment将具有一个公共环境,但是ServerResourceGroup在该环境中可以具有多个服务器。

So from ResourceGroupEnvironment I am trying to join VIP , URL in to servers , but I get duplicate entries for servers, but each entry with different vip and URL . 因此,我试图从ResourceGroupEnvironmentVIPURL加入servers ,但是我得到服务器的重复条目,但是每个条目具有不同的vipURL Please see below duplicate record in JSON for an example: 请参阅以下JSON中的重复记录作为示例:

{
    "serverId": 1,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric",
    "serverName": "Server1",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "192.168.1.1",
    "vip": "10.1.1.1",
    "url": "www.google.com",
    "environmentName": "DEV",
},
{
    "serverId": 1,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric",
    "serverName": "Server1",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "192.168.1.1",
    "vip": "10.2.2.3",
    "url": "www.testui.com",
    "environmentName": "DEV",
}

So whats wrong with above records in JSON? 那么上述JSON中的记录怎么了?

Well I should only get one record back from database for common environment . 好吧,我应该只从数据库中获取一条记录,以获取通用environment If there are multiple servers in DEV environment, then it should return multiple servers, but should join VIP and URL in to each server record. 如果DEV环境中有多个服务器,则它应返回多个服务器,但应将VIPURL连接到每个服务器记录中。 If you notice, VIP and URL are unique, which they belong to two different environments. 如果您注意到, VIPURL是唯一的,它们属于两个不同的环境。 Such as 10.1.1.1 VIP belongs to DEV environment and 10.2.2.3 belongs to other environment PROD . 例如10.1.1.1 VIP属于DEV环境,而10.2.2.3属于其他环境PROD

Here is the query I wrote in linq that is not working as excepted: 这是我在linq中编写的查询,该查询无法正常运行:

var query = from rg in _context.ResourceGroup
            join sr in _context.ServersResourceGroup on rg.Id equals sr.ResourceGroup_id
            join rge in _context.ResourceGroupEnvironment on sr.Environment_id equals rge.Environment_id into lrges
            from lrge in lrges.DefaultIfEmpty()
            join s in _context.Servers on sr.Server_id equals s.Id
            join e in _context.Environments on sr.Environment_id equals e.Id
            join a in _context.Applications on rg.Application_Id equals a.Id
            join d in _context.Domains on s.Domain_Id equals d.Id
            join t in _context.Types on rg.Type_Id equals t.Id
            join o in _context.OperatingSystems on s.OperatingSystem_Id equals o.Id
            join n in _context.NetworkZones on s.NetworkZone_Id equals n.Id
            join stat in _context.Status on s.Status.Id equals stat.Id
            where a.Name.ToLower() == applicationName.ToLower()
            select new SearchListViewModel()
            {
                serverId = s.Id,
                resourceName = rg.Name,
                applicationName = a.Name,
                serverName = s.ServerName,
                aliasName = s.Alias,
                os = o.OSVersion,
                ipAddress = s.IPAddress,
                vip = lrge.VIP,
                url = lrge.EndPointURL,
                domain = d.Name,
                network = n.Name,
                typeName = t.Name,
                environmentName = e.Name,
                status = stat.Name
            };

        return query.ToList();

SQL Query: SQL查询:

When I write my own SQL query, it works fine and gives me correct records. 当我编写自己的SQL查询时,它可以正常工作并提供正确的记录。 Please see below SQL query: 请参见下面的SQL查询:

select rg.Name as ResourceName, s.ServerName, rge.VIP, rge.EndPointURL
from ResourceGroup as rg
join ServersResourceGroup as srg on rg.Id = srg.ResourceGroup_id
join Servers as s on srg.Server_id = s.Id
left join ResourceGroupEnvironment as rge on srg.Environment_id = rge.Environment_id

HERE IS THE SOLUTION THAT WORKED AFTER EVERYONE'S HELP: 这是每个人都可以使用的解决方案:

 var query = from rg in _context.ResourceGroup
                    join srg in _context.ServersResourceGroup on rg.Id equals srg.ResourceGroup_id
                    join s in _context.Servers on srg.Server_id equals s.Id
                    join a in _context.Applications on rg.Application_Id equals a.Id
                    join e in _context.Environments on srg.Environment_id equals e.Id
                    join d in _context.Domains on s.Domain_Id equals d.Id
                    join t in _context.Types on rg.Type_Id equals t.Id
                    join n in _context.NetworkZones on s.NetworkZone_Id equals n.Id
                    join o in _context.OperatingSystems on s.OperatingSystem_Id equals o.Id
                    join stat in _context.Status on s.Status_Id equals stat.Id
                    join rge in _context.ResourceGroupEnvironment on srg.Environment_id equals rge.Environment_id into lrges
                    from lrge in lrges.DefaultIfEmpty()
                    select new SearchListViewModel()
                    {
                        serverId = s.Id,
                        serverName = s.ServerName,
                        aliasName = s.Alias,
                        domain = d.Name,
                        environmentName = e.Name,
                        network = n.Name,
                        os = o.OSVersion,
                        ipAddress = s.IPAddress,
                        vip = lrge == null ? string.Empty : lrge.VIP,
                        url = lrge == null ? string.Empty : lrge.EndPointURL,
                        typeName = t.Name,
                        applicationName = a.Name,
                        resourceName = rg.Name,
                        status = stat.Name
                    };

        return query.ToList();

Your query 您的查询

SELECT rg.Name AS ResourceName, s.ServerName, rge.VIP, rge.EndPointURL
FROM ResourceGroup AS rg
JOIN ServersResourceGroup AS srg ON rg.Id = srg.ResourceGroup_id
JOIN Servers AS s ON srg.Server_id = s.Id
LEFT JOIN ResourceGroupEnvironment AS rge ON srg.Environment_id = rge.Environment_id

Can be translated to this Linq statement 可以翻译成这个Linq语句

var query = from rg in _context.ResourceGroup
    join srg in _context.ServersResourceGroup on rg.Id equals srg.ResourceGroup_id
    join s in _context.Servers on srg.Server_id equals s.Id
    from rge in _context.ResourceGroupEnvironment.Where(x => srg.Environment_id = x.Environment_id).DefaultIfEmpty()
    select new{
        ResourceName = rg.Name, 
        s.ServerName, 
        rge.VIP, 
        rge.EndPointURL
    };
var queryResults = query.ToList();

Again you should really compare apples to apples. 同样,您应该真正将苹果与苹果进行比较。 In your query you are joining 11 tables and you have a where clause which are both omitted from your example query which could be the reason for you different results. 在查询中,您要联接11个表,并且有一个where子句,示例查询中都省略了这两个子句,这可能是导致结果不同的原因。 As per your comment though this answer just focuses on the 4 tables included in your SQL script. 根据您的评论,尽管此答案仅关注SQL脚本中包含的4个表。


About the last (outer) join: See answer on question LEFT OUTER JOIN in LINQ by @Stefan Steiger . 关于最后一个(外部)连接:请参阅@Stefan Steiger 在LINQ中对问题LEFT OUTER JOIN的回答。 This is an easier to read syntax IMO but either that or the other way using the join syntax would work. 这是更易于阅读的IMO语法,但是使用join语法的方法或其他方法都可以使用。

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

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