2013-06-13 12 views
5

この質問を追加する前に、私は同様のものについてはstackoverflowで検索しましたが、私は見つけることができませんでした。インターネット上の質問のほとんどは、文字列(たとえばLIKE '%ABC%'など)でLIKEを使用していましたが、別のテーブルの既存の列と比較する必要があります。LinqのSQL LIKE

私は以下のようにselect文のためのLINQクエリを記述する必要が

- 私はLINQクエリ以下を思い付いたが、期待通りのが機能していない

select * 
from [dbo].[BaseClaim] 
where WPId like (select WPId from UserProfiles where ID='1459') 

-

 var result = (from claimsRow in context.BaseClaims 
          where (from upRow in context.UserProfiles 
           where upRow.ID == 1459 
           select upRow.WPId).Contains(claimsRow.WPId) 
          select claimsRow); 

とSQL linqが生成する上記のとおりです -

SELECT 
    [Extent1].[WPId] AS [WPId] 
    FROM [dbo].[BaseClaim] AS [Extent1] 
    WHERE EXISTS (SELECT 
      1 AS [C1] 
       FROM (SELECT 
         [UserProfiles].[ID] AS [ID], 
         [UserProfiles].[WPId] AS [WPId]  
         FROM [dbo].[UserProfiles] AS [UserProfiles]) AS [Extent2] 
        WHERE (1459 = [Extent2].[ID]) AND ([Extent2].[WPId] = [Extent1].[WPId])) 

私のlinqは、 LIKEの代わりにbaseclaim.wpIDをuserprofiles.wpidと比較します。あなたが使用する必要があります

+0

なぜ 'like'を使用しますか? 'WPId'に'% '文字はありますか? –

+0

@Saiは私の答えを以下に見てください。私はそれがヒットすることを願っています。 – aiapatag

+0

@GertArnoldはいWPIdに%文字があります。 – Sai

答えて

8

をホープ、パターンによって異なります。

  • string.Contains("pattern")LIKE '%pattern%'
  • string.StartsWith("pattern")と等価であるLIKE 'pattern%'
  • string.EndsWith("pattern")と同等ですLIKE '%pattern'

と同等ですが、あなたのSQLクエリでパターンが動的であるので、私は考えていませんそれをまっすぐLinqに変換する良い方法があります。このクエリは、Entity Frameworkの

from claimsRow in context.BaseClaims 
let wpId = context.UserProfiles.Where(upRow => upRow.ID == 1459) 
           .Select(upRow => upRow.WPId) 
           .FirstOrDefault() 
where wpId.Contains(claimsRow.WPId) 
select claimsRow 

で動作しますが、代わりに

var result = 
    from claimsRow in context.BaseClaims 
    let wpId = context.UserProfiles.Single(upRow => upRow.ID == 1459).WPId 
    where claimsRow.WPId.Contains(wpId) // or StartsWith or EndsWith 
    select claimsRow; 

または可能性

var wpId = 
    (from upRow in context.UserProfiles 
    where upRow.ID == 1459 
    select upRow.WPId) 
    .Single(); 
var result = 
    from claimsRow in context.BaseClaims 
    where claimsRow.WPId.Contains(wpId) // or StartsWith or EndsWith 
    select claimsRow; 
+0

Linq to SQLは 'String.Containsメソッドでクライアント上で評価できる引数だけがサポートされています.' –

+0

@lazyberezovskyだから、まずパターンを問い合わせなければならないと思いますか? –

+0

@ p.s.w.g、返信ありがとうございます。あなたのクエリはuserprofilesからwpidを1つだけ返します。すべてのwpidsと比較する必要があります。 – Sai

3

は例

.Where(a => a.Name.Contains("someStrig") 

ため が含まれているパラメータが

一定の場合と同様に生成含まれ、それが直接対応はありませんが、いくつかの方法が同様にそこに動作している

+1

OPは「Contains」を使用しています!これは何も言わない。 –

+0

どういう意味ですか?このようなものを書くことができます。var query =(nameのnameからname.ToUpper()。Contains(someString)select name); – Microtechie

+0

OPは '.Contains(claimsRow.WPId)'を使用しています。あなたはエラーを釘付けにしていない、いくつかの一般的な発言を与えた。 –

1

:あなたがデザイン時にわかっている場合のパターンは、あなたがこれを使用することができ、これらの例1に適合していることLIKEの場合CHARINDEX操作

SELECT * FROM [dbo].[BaseClaims] AS [Extent1] 
LEFT OUTER JOIN (SELECT TOP (1) [Extent2].[WPId] AS [WPId] 
        FROM [dbo].[UserProfiles] AS [Extent2] 
        WHERE [Extent2].[ID] = 1459) AS [Limit1] ON 1 = 1 
WHERE (CHARINDEX([Extent1].[WPId], [Limit1].[WPId])) > 0 

注:クライアント上で評価することができます

だけ引数が String.Contains方法でサポートされています。LINQのは、SQLすると、それは非サポート例外がスローされます。

+1

linq-to-sqlでは、[SqlMethods.Like](http://msdn.microsoft.com/en-us/library/bb340785.aspx)を使用する必要があります。しかし、これはEFです。 –

+0

@GertArnoldありがとう、私はいつも 'SqlMethods'について忘れています:) –

0

EDITED:

はアスカーは、彼がSQLでワイルドカードのように動作するはずの彼UserProfile.WPIdでワイルドカード(%)を持っていると述べました。

あなたは、このいずれかを使用できます。

BaseClaims.Where(b => UserProfiles.Where(u => u.ID == "1459").Any(u => u.WPId.Contains(b.WPId))).ToList();

をこの例では、私はあなたのエンティティ/テーブルを模倣しようとしています。

static void Main(string[] args) 
    { 
     List<BaseClaim> BaseClaims = new List<BaseClaim>() 
     { 
      new BaseClaim(){ WPId = "11123411" }, //match 1 
      new BaseClaim(){ WPId = "11123123" }, //match 2 
      new BaseClaim(){ WPId = "44423411" }, //match 3 
      new BaseClaim(){ WPId = "444AAAA" }, //match 3 
      new BaseClaim(){ WPId = "444BBBB" }, //match 3 
      new BaseClaim(){ WPId = "444QWQEQW" }, //match 3 
      new BaseClaim(){ WPId = "2314" }, 
      new BaseClaim(){ WPId = "3214" } 
     }; 
     List<UserProfile> UserProfiles = new List<UserProfile>() 
     { 
      new UserProfile(){ WPId="%112341%", ID="1459" }, //match 1 
      new UserProfile(){ WPId="%123", ID="1459" }, //match 2 
      new UserProfile(){ WPId="444%", ID="1459" }, //match 3 
      new UserProfile(){ WPId="5555", ID="1459" }, 
      new UserProfile(){ WPId="2222", ID="1459" }, 
      new UserProfile(){ WPId="1111", ID="4444" }, 
     }; 

     char[] asterisk = { '%' }; 
     List<BaseClaim> result = BaseClaims.Where(b => UserProfiles.Where(u => u.ID == "1459").Any(u => u.WPId.StartsWith("%") && u.WPId.EndsWith("%") ? b.WPId.Contains(u.WPId.Trim(asterisk)) : 
                             u.WPId.StartsWith("%") ? b.WPId.EndsWith(u.WPId.Trim(asterisk)) : 
                             u.WPId.EndsWith("%") ? b.WPId.StartsWith(u.WPId.Trim(asterisk)) : 
                             false)).ToList(); 
     //this will result to getting the first 3 BaseClaims 

    } 
+0

返事ありがとう。 userProfilesのWPIDには "%12"という形式の値が含まれていますので、クエリを実行しようとすると値は返されません。 – Sai

+0

@Saiそれを今すぐチェックしてください。 :) – aiapatag

+0

"System.String Trim(Char []) 'メソッドは、トリム文字が引数として指定されていない場合、LINQ to Entitiesでのみサポートされています。私が気づいたことの他に、カラムからwildchar(%)を取り除くことはできません。時にはwildcharが途中にあることがあるからです。 – Sai