【问题标题】:Issue getting correct results from LINQ query with LEFT JOIN使用 LEFT JOIN 从 LINQ 查询中获取正确结果的问题
【发布时间】:2016-11-14 23:16:16
【问题描述】:

我正在 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 中完成上述本机查询,

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

非常感谢任何帮助。

谢谢,

【问题讨论】:

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


    【解决方案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()
    

    【讨论】:

    • 成功了。我一直在寻找几天来了解如何使用多个条件,现在这很有意义。非常感谢。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-26
    • 2016-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多