繁体   English   中英

SQL查询到LINQ联接5个表

[英]SQL query to LINQ to join 5 tables

我有五个试图从中获得结果的表。 下面是我的桌子设计。

应用程序和环境表:

Id, Name

注意-上面的两个表都具有相同的属性。

ResourceGroup表:

Id, Name, Application_Id

ResourceGroupEnvironment表:

Id, ResourceGroup_Id, Environment_Id, VIP, URL

服务器表:

Id, ServerName, Alias, IPAddress, Network

ServerResourceGroup表:

Id, Server_Id, ResourceGroup_Id, Environment_Id

我想要得到什么结果?

基于上述表设计,我希望获得属于ResourceGroupApplication表的所​​有服务器。 ResourceGroupEnvironmentServerResourceGroup表共享environment表,其中ResourceGroupEnvironment将具有一个公共环境,但是ServerResourceGroup在该环境中可以具有多个服务器。

因此,我试图从ResourceGroupEnvironmentVIPURL加入servers ,但是我得到服务器的重复条目,但是每个条目具有不同的vipURL 请参阅以下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",
}

那么上述JSON中的记录怎么了?

好吧,我应该只从数据库中获取一条记录,以获取通用environment 如果DEV环境中有多个服务器,则它应返回多个服务器,但应将VIPURL连接到每个服务器记录中。 如果您注意到, VIPURL是唯一的,它们属于两个不同的环境。 例如10.1.1.1 VIP属于DEV环境,而10.2.2.3属于其他环境PROD

这是我在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查询:

当我编写自己的SQL查询时,它可以正常工作并提供正确的记录。 请参见下面的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

这是每个人都可以使用的解决方案:

 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();

您的查询

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

可以翻译成这个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();

同样,您应该真正将苹果与苹果进行比较。 在查询中,您要联接11个表,并且有一个where子句,示例查询中都省略了这两个子句,这可能是导致结果不同的原因。 根据您的评论,尽管此答案仅关注SQL脚本中包含的4个表。


关于最后一个(外部)连接:请参阅@Stefan Steiger 在LINQ中对问题LEFT OUTER JOIN的回答。 这是更易于阅读的IMO语法,但是使用join语法的方法或其他方法都可以使用。

暂无
暂无

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

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