5

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

以下のように、select ステートメントの linq クエリを記述する必要があります。

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

以下のlinqクエリを思いつきましたが、期待どおりに機能しません-

     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);

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

   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]))

したがって、baseclaim.wpID を LIKE ではなく userprofiles.wpid と比較しているため、私の linq が機能していないことは明らかです。

4

4 に答える 4

8

直接同等のものはありませんが、パターンによっては、同様に機能するメソッドがいくつかあります。

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

ただし、SQL クエリではパターンが動的であるため、Linq に直接変換する良い方法はないと思います。設計時にパターンがこれらのケースのいずれかに適合することがわかっている場合は、これを使用できます。

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;
于 2013-06-13T07:11:12.733 に答える
1

このクエリは 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

しかし、代わりに操作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

注: Linq to SQL を使用すると、NotSupportedException がスローされます。

String.Contains メソッドでは、クライアントで評価できる引数のみがサポートされています。

于 2013-06-13T07:11:24.017 に答える
0

編集:

%質問者は、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

    }
于 2013-06-13T07:25:05.630 に答える