[英]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
我想要得到什么结果?
基于上述表设计,我希望获得属于ResourceGroup
和Application
表的所有服务器。 ResourceGroupEnvironment
和ServerResourceGroup
表共享environment
表,其中ResourceGroupEnvironment
将具有一个公共环境,但是ServerResourceGroup
在该环境中可以具有多个服务器。
因此,我试图从ResourceGroupEnvironment
将VIP
和URL
加入servers
,但是我得到服务器的重复条目,但是每个条目具有不同的vip
和URL
。 请参阅以下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
环境中有多个服务器,则它应返回多个服务器,但应将VIP
和URL
连接到每个服务器记录中。 如果您注意到, VIP
和URL
是唯一的,它们属于两个不同的环境。 例如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.