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

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

新規登録して質問してみよう
ただいま回答率
85.49%
C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

2回答

7289閲覧

C#のLINQでSQL文を文字列でわたすには

MiyamotoSatoshi

総合スコア30

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

0クリップ

投稿2016/05/26 10:41

Unityにて絞り込み機能を作成しようと思っており、
SQL文をList型に適応したいのですが検索しても見つからず詰まってしまいました。

タイプが1~6まであり、それぞれボタンと連動しています。

ボタンはトグルになっていてタイプ1とタイプ3が選択状態であれば、
タイプ1とタイプ3に合致するデータのみを表示します。

下記のようなWHERE句をLINQに渡したいのですがどのようにしたら良いかがわかりません。
"WHERE Type == タイプ1 OR rarity == タイプ3"

●環境
Unity5.3.4
.NetFrameWork:3.5(C#3.0相当)

よろしくお願いします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

lang

1var list = new List<SampleData>(); 2var result = list.Where(data => data.Type == "type1" || data.Rarity == "type3");

上記のようなラムダ式による抽出を動的に行う方法です。

lang

1var parameters = Expression.Parameter(typeof(SampleData), "data"); 2var body = Expression.OrElse( 3 Expression.Equal(Expression.PropertyOrField(parameters, "Type"), Expression.Constant("type1", typeof(string))), 4 Expression.Equal(Expression.PropertyOrField(parameters, "Rarity"), Expression.Constant("type3", typeof(string)))); 5var lambda = Expression.Lambda<Func<SampleData, bool>>(body, parameters); 6var predicate = lambda.Compile(); 7 8var list = new List<SampleData>(); 9var result = list.Where(data => predicate(data));

更に、選択されたボタンからbodyにあたる部分を動的に生成することで、
希望される処理が可能かと思います。

<参考>
http://www.atmarkit.co.jp/fdotnet/dotnettips/986dynamiclinq/dynamiclinq.html

投稿2016/05/27 08:02

TAKA_0921

総合スコア234

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MiyamotoSatoshi

2016/05/28 08:11 編集

ご返信ありがとうございます、 条件が2つものに関しては下記ソースでできました。 Expression.OrElseは2つの引数にしか対応していないようなのですが 3つ以上あった場合はどのようにすれば良いのでしょうか? ```C# List<testClass> testClassList = new List<testClass>(); public class testClass { public int ValInt; public int ValType; public string ValString; public bool ValBool1; public bool ValBool2; } public void OnClickButton() { for(int i = 0; i < 5; i++) { testClass testData = new testClass(); testData.ValInt = i; testData.ValType = i * 2; testData.ValString = i.ToString(); testData.ValBool1 = i % 2 == 0 ? true : false; testData.ValBool2 = i % 2 == 1 ? true : false; testClassList.Add(testData); } var parameters = Expression.Parameter(typeof(testClass), "data"); var body = Expression.OrElse( Expression.Equal(Expression.PropertyOrField(parameters, "ValString"), Expression.Constant("2", typeof(string))), Expression.Equal(Expression.PropertyOrField(parameters, "ValString"), Expression.Constant("4", typeof(string)))); var lambda = Expression.Lambda<Func<testClass, bool>>(body, parameters); var predicate = lambda.Compile(); var list = new List<testClass>(); var result = testClassList.Where(data => predicate(data)); foreach(var data in result) { Debug.Log("ValBool1=" + data.ValBool1.ToString()); Debug.Log("ValBool2=" + data.ValBool2.ToString()); Debug.Log("ValInt=" + data.ValInt.ToString()); Debug.Log("ValString=" + data.ValString); Debug.Log("ValType=" + data.ValType.ToString()); } } ```
TAKA_0921

2016/05/28 21:39 編集

ラムダ式右辺の各式のExpressionをA, B, Cとする場合、 Expression.OrElse(Expression.OrElse(A, B), C) とすることで、 ((A || B) || C) という形ではありますが3つ以上のOrElseにも対応は可能です。 例えば、A,B,C,…の各Expressionを var expressions = new List<Expression>(); として持ち、 var body = expressions.Aggregate((x, y) => Expression.OrElse(x, y)); などとすることで生成することが出来るのではないでしょうか。
MiyamotoSatoshi

2016/05/29 15:58

例題までご提示いただきありがとうございます。 貼り付けたソースコードの一部を下記に変更したら3つにも対応できました。 var body = Expression.OrElse( Expression.Equal(Expression.PropertyOrField(parameters, "ValString"), Expression.Constant("2", typeof(string))), Expression.Equal(Expression.PropertyOrField(parameters, "ValString"), Expression.Constant("4", typeof(string)))); var body1 = Expression.OrElse( body, Expression.Equal(Expression.PropertyOrField(parameters, "ValString"), Expression.Constant("0", typeof(string)))); Aggregateがわかってなかったのでちょっと調べたのですが、 集計してくれるというか1つにまとめてくれるもののようなので List内のExpressionをまとめてくれるのではと思ってます。 デバッグで動作を見ながらbodyにまとめた結果が格納されるかチェックしてみます。
guest

0

比較対象となるフィールド数が可変(検証するボタンの種類が可変)の場合、Linq for Objects では、対象フィールドの値だけを含んだリストを作成し、これと join することで該当するオブジェクトだけを抽出するのが良いと思います。

具体的には・・・

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4 5class A { 6 public string Name; 7 public int Type; 8 public A(string n, int t) { 9 Name = n; 10 Type = t; 11 } 12} 13 14class MainClass { 15 static void Main() { 16 int[] type_array = {2,4}; 17 A[] a_array = { 18 new A("name1-1", 1), 19 new A("name1-2", 1), 20 new A("name2-1", 2), 21 new A("name2-2", 2), 22 new A("name2-3", 2), 23 new A("name3-1", 3), 24 new A("name4-1", 4), 25 new A("name4-2", 4), 26 new A("name4-3", 4), 27 new A("name5-1", 5), 28 new A("name5-2", 5) 29 }; 30 31 var result = 32 from a in a_array 33 join t in type_array on a.Type equals t 34 select a; 35 36 foreach(var a in result) { 37 Console.WriteLine("Name = " + a.Name); 38 } 39 } 40} 41 42// 出力 43// Name = name2-1 44// Name = name2-2 45// Name = name2-3 46// Name = name4-1 47// Name = name4-2 48// Name = name4-3

このように書くことができます。 このサンプルコードでは type_array 配列の内容が変化しても、該当するオブジェクトを抽出できます。

ご参考になれば。

投稿2016/05/26 15:31

tkanda

総合スコア2425

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問