質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • C#

    7449questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio 2013

    309questions

    Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

  • ASP.NET MVC Framework

    64questions

    ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

  • LINQ to SQL

    10questions

    LINQ to SQLは.NET Framework 3.5のコンポーネントで、リレーショナル データをオブジェクトとして管理するためのランタイム インフラストラクチャを提供します。

LINQtoSQLでのWHEREのエラーについて

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,524

DinKa

score 31

前提・実現したいこと

システムを実装するにあたって、データの紐付の設計を行いました。
しかし、どうしても設計通りにいかなくて困っています。
とくにSQLServerで引くことは可能であるのに、LINQtoSQLではうまくかけなかったりします。
私自身のC#の知識不足にも起因すると思いますが、調べてもどうしても行き詰ってしまったもので質問させてください。

発生している問題・エラーメッセージ

WHERE句でエラーが発生しています。
foreachが邪魔しているような気がしますが、なぜ以下のようなエラーになるのかがわかりません。

エラー    3    演算子 '>=''string''int' 型のオペランドに適用することはできません。
エラー    1    演算子 '&&''bool''ラムダ式' 型のオペランドに適用することはできません。
エラー    2    ローカルの変数 'SET_B' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'SET_B' の意味が変更されるのを避けるためです。

該当のソースコード

class Bind
{

    private void Bind(string key)
    {
        /// アウトプット用のコレクションです。
        LIST<OUT_PUT> output = new List<OUT_PUT>();
        /// keyが複数指定されることもあるので、まずは1件(先頭)だけ取り出す設定にしてみました。 
        var key_id = (from a in HIS
                      where key = a.id1
                      select a.id1).FirstOrDefault();
        /// 目標のid1を検索して、マスタに登録されているcodeと関連付けます。
        var target = from b in HIS
                     join c in MST on b.code1 equals c.code
                     where key_id == b.id1
                     && c.name == 'A'
                     select new
                     {
                         key_id,
                         A_id = b.id1,
                         A_no1 = b.no1,
                         B_no2 = b.no2,
                         B_id = b.id2
                     };
        /// 1行ずつコレクションに追加していきたいため、foreachで繰り返します。
        foreach (var SET_A in target)
        {
            /// 関連付け先のcodeのマスタがBであるかをチェックして、1件づつ紐づけます。
            var SET_B = (from d in HIS
                         join e in MST on d.code1 equals e.code
                         where SET_A.B_id = d.id1
                         && e.name == 'B'
                         select new
                         {
                             key_id,
                             SET_A.A_id,
                             SET_A.A_no1,
                             SET_A.B_no2,
                             SET_A.B_id,
                             B_no1 = d.no1,
                             C_no2 = d.no2,
                             C_id = d.id2,
                         }).FirstOrDefault();

            /// さらに関連付けますが、この時にnoの条件によって、紐付対象が変わっていきます。
            var SET_C = (from f in HIS
                         where (SET_B.B_no1 = f.id1
                         && (int.Parse(SET_B.B_no2) >= 1 && int.Parse(SET_B.B_no2) <= 5 
                         && int.Parse(f.no1) >= 6 && int.Parse(f.no1) <= 10)
                         || (int.Parse(SET_B.B_no2) >= 6 && int.Parse(SET_B.B_no2) <= 10
                         && int.Parse(f.no1) >= 1 && int.Parse(f.no1) <= 5))
                         select new
                         {
                             key_id,
                             SET_B.A_id,
                             SET_B.A_no1,
                             SET_B.B_no2,
                             SET_B.B_id,
                             SET_B.B_no1,
                             SET_B.C_no2,
                             SET_B.C_id,
                             C_no1 = f.no1,
                             D_no2 = f.no2,
                             D_id = f.id2
                         }).DISTINCT();

            /// 1配列づつoutput用のコレクションに追加していきます。
            IF(SET_C != null);
            {
                out_put.AddRange(SET_C);
            }
        }
    }
}

試したこと

LINQ での条件を絞り込み(WHERE句)を一通り調べてみましたがわかりませんでした(参考書では問題なかったです)。
また、in ['1'-'5']のような範囲選択も使えませんでした。

補足情報(言語/FW/ツール等のバージョンなど)

C# ASP.NET MVC Framework、VisualStadio2013、SQLServer2014
質問者のC#のプログラミング能力はあまり高くはありません。
著:高橋麻奈のやさしいC#を一通り読みましたが、オブジェクト指向がいまいちまだふんわりした感じです。

必要なテーブル(HIS、MST)と、出力目標の(OUTPUT)のExcelを以下にアップロードしました。
HIS-MST-OUTPUT
よろしくお願いいたします。

※エラーは一通り修正したものを掲載してあります。修正前をご覧になりたい方は、質問編集履歴を確認してください。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • TAKA_0921

    2016/05/21 02:59

    記載されたソースコードはVisual Studio等で記述したものと同一でしょうか? 「LIST」や「where key = a.id1」や「})DISTINCT();」など、 何となくやりたいことは伝わってきますがC#の書き方ではないように感じますし、 発生している問題の再現性を高めるためにも同一のソースコードを掲載された方が 回答しやすくなると思います。

    キャンセル

  • DinKa

    2016/05/21 03:10

    はい、確かに同一ではないです。 VisualStudioで記述したものをそのまま掲載すると、問題がわかりにくくなると思ったので、自分で設計したSQL抽出内容を元にC#風に作り替えました。 やはり、遠回りでも質問用の環境を構築したほうが良いのでしょうか。

    キャンセル

  • TAKA_0921

    2016/05/21 03:38 編集

    環境を作り直す必要はないと思いますが、ソースコードを見た限りではビルドの時点で質問に記述されたこと以上の量のエラーが表示されると思われます。文字の大小や括弧の数、"."の抜け等問題の箇所以外は正常な記述にするか、あるいはコンパイルエラーを解決するだけであれば該当箇所のソースコードのみでも問題ないのではと思いました。

    キャンセル

  • DinKa

    2016/05/21 03:42

    確かに今見てみるとかなりミスがあるようです。 その部分だけでも環境に乗せて修正して再アップしてみます。

    キャンセル

回答 1

checkベストアンサー

+1

「⇒」が付いている行の部分に関してとりあえず2点確認させてください。

  1. B_no2のデータ型がstringになっていませんか?
    stringintを比較演算子>=を使用して比較することは出来ません。

  2. f.no1 => 6及びf.no1 => 1の部分はそれぞれ、
    f.no1 >= 6及びf.no1 >= 1と書くべきではありませんか?
    =>はラムダ式にて使用されるラムダ演算子です。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/05/21 02:59

    深夜に回答ありがとうございます。

    はい、確かにstringです、数値もすべてString型で登録されています。
    intでキャストしようとしたらエラーになりました、当然でしょうけど。
    また、評価数字を’1’としてもダメでした。

    =>は自動でラムダ式のラムダ演算子になるのですね、ラムダ式では確かそういう作法があることを知っていましたが、SQL式の途中に出現しても認識されてしまうのですね。ラムダ式を使ったことがないのもありますが、今まで知りませんでした。

    >=の部分は、=>に修正してみます。

    キャンセル

  • 2016/05/23 09:36

    大変遅くなりましたが、=>については、>=に修正したところ該当項目に関してエラーがなくなりました。
    また、修正済みの該当ソースコードを掲載させていただきましたが、
    LIST<OUT_PUT>、MST、HISに関しては該当データベースやコンストラクタの定義がないのでエラーは出てしまっていますが、それ以外はエラーは出なくなりました。

    問題は、実際に構築しているほうの環境ではやはり>=の演算子でエラーが出てしまいます。

    エラー 1 演算子 '>=' を 'string' と 'char' 型のオペランドに適用することはできません。
    エラー 2 演算子 '>=' を 'string' と 'char' 型のオペランドに適用することはできません。

    キャンセル

  • 2016/05/23 09:44

    「"1"」と「'1'」はC#では異なる型です
    前者はstring,後者はcharです。
    文字列からParse()して数値として比較したほうがいいと思います。

    キャンセル

  • 2016/05/23 09:50

    ありがとうございます、SQLServerで弄ってばかりいたので、そのままにしてしまいました。
    修正したところ、エラー 1 演算子 '>=' を 'string' と 'string' 型のオペランドに適用することはできません。
    と出ましたので、これを数値型にキャストすればいいのでしょうか?

    キャンセル

  • 2016/05/23 09:56 編集

    int.Parse()で要素をint型に変換したところ、エラーがなくなりました。
    初歩的なところを教えていただいてありがとうございました。

    キャンセル

関連した質問

同じタグがついた質問を見る

  • C#

    7449questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • Visual Studio 2013

    309questions

    Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

  • ASP.NET MVC Framework

    64questions

    ASP.NET MVC Frameworkは、MVCパターンをベースとした、マイクロソフトのウェブアプリケーション開発用のフレームワークです。

  • LINQ to SQL

    10questions

    LINQ to SQLは.NET Framework 3.5のコンポーネントで、リレーショナル データをオブジェクトとして管理するためのランタイム インフラストラクチャを提供します。