使用LEFT JOIN从LINQ查询中获取正确结果的问题

时间:2016-11-14 13:17:31

标签: asp.net-mvc entity-framework linq

我正在LINQ中编写一个查询,但是从数据库中获取正确记录时遇到问题。当我执行LINQ查询时,我得到重复的记录。请参阅以下记录,其中包含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.5",
    "url": "www.testapp.com",
    "domain": "Domain1",
    "network": "Internal Harden",
    "typeName": "Application",
    "environmentName": "DEV",
    "status": "Active"
  },
  {
    "serverId": 1,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric",
    "serverName": "Server1",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "192.168.1.1",
    "vip": "",
    "url": "",
    "domain": "Domain1",
    "network": "Internal Harden",
    "typeName": "Application",
    "environmentName": "DEV",
    "status": "Active"
  },
  {
    "serverId": 2,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric",
    "serverName": "Server2",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "192.168.1.2",
    "vip": "10.1.1.5",
    "url": "www.testapp.com",
    "domain": "Domain1",
    "network": "Internal Harden",
    "typeName": "Application",
    "environmentName": "DEV",
    "status": "Active"
  },
  {
    "serverId": 2,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric",
    "serverName": "Server2",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "192.168.1.2",
    "vip": "",
    "url": "",
    "domain": "Domain1",
    "network": "Internal Harden",
    "typeName": "Application",
    "environmentName": "DEV",
    "status": "Active"
  },
  {
    "serverId": 3,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric UI",
    "serverName": "Server3",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "172.16.1.1",
    "vip": "",
    "url": "",
    "domain": "Domain2",
    "network": "DMZ 1",
    "typeName": "Application",
    "environmentName": "DEV",
    "status": "Active"
  },
  {
    "serverId": 3,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric UI",
    "serverName": "Server3",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "172.16.1.1",
    "vip": "10.1.1.6",
    "url": "www.testappui.com",
    "domain": "Domain2",
    "network": "DMZ 1",
    "typeName": "Application",
    "environmentName": "DEV",
    "status": "Active"
  },
  {
    "serverId": 4,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric UI",
    "serverName": "Server4",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "172.16.1.2",
    "vip": "",
    "url": "",
    "domain": "Domain2",
    "network": "DMZ 1",
    "typeName": "Application",
    "environmentName": "DEV",
    "status": "Active"
  },
  {
    "serverId": 4,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric UI",
    "serverName": "Server4",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "172.16.1.2",
    "vip": "10.1.1.6",
    "url": "www.testappui.com",
    "domain": "Domain2",
    "network": "DMZ 1",
    "typeName": "Application",
    "environmentName": "DEV",
    "status": "Active"
  },
  {
    "serverId": 1002,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric",
    "serverName": "Server5",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "10.1.1.5",
    "vip": "",
    "url": "",
    "domain": "Domain1",
    "network": "Internal Harden",
    "typeName": "Application",
    "environmentName": "INT",
    "status": "Active"
  },
  {
    "serverId": 1003,
    "applicationName": "TestApp",
    "resourceName": "Test AppFabric",
    "serverName": "server6",
    "aliasName": null,
    "os": "Windows Server 2008",
    "ipAddress": "10.1.1.6",
    "vip": "",
    "url": "",
    "domain": "Domain1",
    "network": "Internal Harden",
    "typeName": "Application",
    "environmentName": "INT",
    "status": "Active"
  }
]

以下是我在ASPT.NET Core应用程序中使用的查询:

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.Where(r => r.ResourceGroup_id == sr.ResourceGroup_id).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,
        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();

此外,这是本机SQL查询,它可以正常工作。

SELECT s.ServerName, rg.Name as ResourceGroup, e.Name as Env,  
rge.EndPointURL, rge.VIP  
FROM ResourceGroup as rg  
JOIN ServersResourceGroup as srg on rg.Id = srg.ResourceGroup_id  
JOIN Servers as s on srg.Server_id = s.Id  
JOIN Environments as e on srg.Environment_id = e.Id  
LEFT JOIN ResourceGroupEnvironment as rge on srg.Environment_id = rge.Environment_id and rg.Id = rge.ResourceGroup_Id  

不确定我的LINQ查询是否错误,但我试图在LINQ中完成上述本机查询,

这是我的实体模型,以帮助理解要求:

enter image description here

非常感谢任何帮助。

谢谢,

1 个答案:

答案 0 :(得分:1)

首先,我在结果中看不到任何重复(每个“结果集”都不同)。

现在,左连接中有一些奇怪的东西,在左连接项上使用Where子句。

join rge in _context.ResourceGroupEnvironment on sr.Environment_id equals rge.Environment_id into lrges
from lrge in lrges.Where(r => r.ResourceGroup_id == sr.ResourceGroup_id).DefaultIfEmpty() 

我宁愿使用多个条件(使用new

进行联接
join rge in _context.ResourceGroupEnvironment on new{sr.Environment_id, sr.ResourceGroup_id} equals new{ rge.Environment_id, rge.ResourceGroup_id} into lrges
from lrge in lrges.DefaultIfEmpty()