2016-10-27 30 views
0

私は結果を得ようとしている5つのテーブルを持っています。私のテーブルデザインは以下の通りです。5つのテーブルを結合するLINQへのSQLクエリ

アプリケーションと環境テーブル:

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は1つの共通環境を持ちますが、ServerResourceGroupはその環境に複数のサーバーを持つことができます。

のでResourceGroupEnvironmentから私はserversにしてVIPURLに参加しようとしていますが、私は、サーバー用の重複したエントリを取得するが、異なる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のデータベースから1つのレコードを返すべきです。 DEV環境に複数のサーバーがある場合は、複数のサーバーを返す必要がありますが、各サーバーレコードにはVIPURLを結合する必要があります。気付くと、VIPURLは一意であり、2つの異なる環境に属します。 10.1.1.1 VIPDEVに属し、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 

はEVERYONE'S HELP AFTER働いたソリューションです:

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

ナビゲーションプロパティを設定しましたか?もしそうなら、あなたはそれらを照会してみるべきです。私はテーブルの束に参加するよりも簡単にそれを見つける。 –

+0

ああ、そうではありません。私はおそらくそれを調べるべきです。 :) – Ray

+1

私はあなたのLinqステートメントで11個のジョインをカウントし、 "手書き" SQLステートメントでは4個をカウントします。同様の状況で結果を得るためにテストしている場合、それらがどのように同じと見なされるかは実際にはわかりません。また、データベースの照合で大文字と小文字が区別されない場合、 '.ToLower() 'との比較を使用する理由はありません – Igor

答えて

1

あなたのクエリ

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で質問LEFT OUTER JOIN in LINQの答えを参照してください。これは文法IMOを読むのが簡単ですが、join構文を使用して、またはそれ以外の方法でも動作します。

+1

こんにちは、あなたの例は私の進歩を助け、左結合を成功させることができました。私は私の質問の答えの掲示板で私の質問に私の答えを提供します。 – Ray

関連する問題