[英]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. 基于上述表设计,我希望获得属于
ResourceGroup
和Application
表的所有服务器。 ResourceGroupEnvironment
and ServerResourceGroup
table shares environment
table where ResourceGroupEnvironment
will have one common environment, but ServerResourceGroup
can have multiple servers in that environment. ResourceGroupEnvironment
和ServerResourceGroup
表共享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
. 因此,我试图从
ResourceGroupEnvironment
将VIP
和URL
加入servers
,但是我得到服务器的重复条目,但是每个条目具有不同的vip
和URL
。 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
环境中有多个服务器,则它应返回多个服务器,但应将VIP
和URL
连接到每个服务器记录中。 If you notice, VIP
and URL
are unique, which they belong to two different environments. 如果您注意到,
VIP
和URL
是唯一的,它们属于两个不同的环境。 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.