2011-08-10 14 views
0

私はテーブル形式でデータを表示するASP.NET MVCアプリケーションがあります。テーブルを検索するので、テキスト文字列を取得してサービスレイヤーに渡して、Linq to Entitiesを使ってクエリを作成します。どのように私は何かを複製することができますfooからsomeintegerどこのエンティティにLinqの '%50%'のように?

文字列を使用していくつかの列を検索したいと思います。 ids)、ユーザーは整数や文字列については気にしません。「1200」と入力し、注文番号に「1200」、または住所に「1200」を入力します。

問題は次のとおりです。 Linq-to-Entitiesクエリを構築する方法を見つけることができませんこのようになりますSQLでの結果:

select orderid, address from orders where orderid like '%1200%' or address like '%1200%' 

データベースコンテキスト:

public DbSet<Person> Persons { get; set; } 
    public DbSet<Worker> Workers { get; set; } 
    public DbSet<WorkerSignin> WorkerSignins { get; set; } 

PersonsWorkersテーブルは1 0..1の関係にあります。ワーカーレコードが存在する場合は、個人レコードも存在する必要があります。彼らは同じIDを共有します。ただし、ワーカーレコードは存在する必要はありません。

テーブルWorkersWorkerSigninsテーブルは関連していますが、クライアント要件のために強制されていません。ワーカーにはバーコード番号の付いたIDカード(dwccardnum)がありますが、発行されたカードとDBに記録されたレコードの間に矛盾があることがあるので、一致するレコードがあるかどうかに関係なく、WorkerSigninsWorkersテーブル。ここで

は、私が働いているコードです:

  allWSI = signinRepo.GetAllQ() 
       .Where(jj => jj.dateforsignin == date) 
       .Select(a => a); 

      if (!string.IsNullOrEmpty(search)) 
      { 
       allWSI = allWSI 
        .Join(workerRepo.GetAllQ(), s => s.dwccardnum, w => w.dwccardnum, (s, w) => new { s, w }) 
        .DefaultIfEmpty() 
        .Join(personRepo.GetAllQ(), oj => oj.w.ID, p => p.ID, (oj, p) => new { oj, p }).DefaultIfEmpty() 
        .DefaultIfEmpty() 
        .Where(jj => Convert.ToString(jj.oj.w.dwccardnum).Contains(search) || 
           jj.p.firstname1.Contains(search) || 
           jj.p.firstname2.Contains(search) || 
           jj.p.lastname1.Contains(search) || 
           jj.p.lastname2.Contains(search)) 
        .Select(a => a.oj.s); 
      } 

GetAllQ()メソッドは、のIQueryable()オブジェクトを返します。

問題は、この行にある: .Where(jj => Convert.ToString(jj.oj.w.dwccardnum).Contains(search) ||

私はこのエラーを取得する:エンティティへ LINQは方法「可能System.StringのToString(Int32)を」メソッドを認識しない、そしてこの方法はに翻訳することはできません店舗の表現「私は改宗を取り出し、このしようとした場合

.Where(jj => jj.oj.w.dwccardnum.Contains(search) ||

が、私はこのエラーを取得: 『INT』は 『入って』の定義と最高の電子が含まれていませんXTensionメソッドオーバーロード「System.Linq.ParallelEnumerable.Contains(System.Linq.ParallelQuery、TSOURCE)は、」そこで質問があり、いくつかの無効な引数

を持っている... 句は、などを生成するために、どこでどのようにして構築します'%string%'を実行し、Linq to Entitiesを使用して整数列に対して実行しますか? (例えば、SQLにLINQを使用せずに)

答えて

2

1つのオプションは、

jj => Convert.ToString(jj.oj.w.dwccardnum).Contains(search) 

...:

jj => SqlFunctions.StringConvert((decimal)jj.oj.w.dwccardnum).Contains(search) 

SqlFunctionsは、名前空間System.Data.Objects.SqlClientで静的クラスであり、私はそれが唯一のSQL Serverで動作します信じています。 StringConvertにはintのオーバーロードがなく、キャストなしでは、明白なオーバーロードを明白に選択できないという不満があるので、decimalへの変わったキャストが必要です。 (それはdecimal?のものとdouble?のものがあります)しかし、私は上記のコードが実際に動作することを(SQL Serverの場合、dwccardnumはintと仮定して)テストしました。

+0

それは動作します。オブジェクトサービス層(私はそれが正しいレイヤーだと思う)のSQLは非常に非効率的に見えます...弾丸を噛んでExpression Treeのビルディングに行く時間があるかもしれません... – JCii

0

あなたが最初の検索がintであるかどうかを確認し、それがある場合は、あなたのLINQでそれを使用するためにチェックしている、基本的にこの

  if (!string.IsNullOrEmpty(search)) 
      { 
       int cardnum; 
       bool searchIsInt = int.TryParse(search, out cardnum); 

       allWSI = allWSI 
        .Join(workerRepo.GetAllQ(), s => s.dwccardnum, w => w.dwccardnum, (s, w) => new { s, w }) 
        .DefaultIfEmpty() 
        .Join(personRepo.GetAllQ(), oj => oj.w.ID, p => p.ID, (oj, p) => new { oj, p }).DefaultIfEmpty() 
        .DefaultIfEmpty() 
        .Where(jj => (searchIsInt ? jj.oj.w.dwccardnum == cardnum : true) || 
           jj.p.firstname1.Contains(search) || 
           jj.p.firstname2.Contains(search) || 
           jj.p.lastname1.Contains(search) || 
           jj.p.lastname2.Contains(search)) 
        .Select(a => a.oj.s); 
      } 

を試してみてください。

+0

お返事ありがとうございます。それは私が探しているものではありません。なぜなら、整数の比較(==)が(部分的に一致する)と思うからです。ユーザーが検索文字列に '120'を入力すると、120,1201,1202,851201などと一致します。 私があなたの提案しているものが '%like 120%'につながるとは信じられません結果のSQL ...私はそれを試しに行くでしょう。 – JCii

+0

あなたは部分検索について正しいです、120は1201でなく120だけを探します。また、構文エラーがありました - >パラメータとしてcardnumを追加しました – evasilchenko

関連する問題