ふと、|演算子(パイプ演算子)を使って、データベースのストリームを検索できたら、何かできるのではなかろうか…と骨休めがてらちょっと。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | public class Test { public void test001() { var db = new DB{ ConnectionString= "" }; RESULT items = db | "person" | "familyname" .EQ( "masuda" ) | "age" .GE(20) | "*" ; RESULT items2 = db | "person" | "familyname" .EQ( "masuda" ) | "age" .GE(20) | "id" | "familyname" | "lastname" ; } public void test002() { var db = new DB { ConnectionString = "" }; RESULT items = db | "person" | (EQ) "familyname" % "masuda" | // familyname == "masuda" と同じ (UP) "age" % 20 | // age >= 20 と同じ "*" ; } public void test003() { // これが直感的で良い var db = new DB { ConnectionString = "" }; RESULT items = db | "person" | // テーブルを指定 (OP) "familyname" == "masuda" | // 検索条件 (OP) "age" >= 20 | "*" ; // 出力 } } |
データストリームというよりも、擬似LINQ構文になっちゃった感じで、あまり意味がありませんが。|演算子のオーバーライドと、暗黙の型変換(implicit)を駆使すると、こんな風に書けますという例です。
データの比較を行うときに、”カラム名”.EQ(値) のように、最初はメソッド名を考えてみたのですが、あまり可読性がよくないので、「==演算子」等もオーバーライドすることにしました。
OP クラスのところが肝で、テーブルのカラム名(文字列)を一度 OP クラスにキャストしてから使うという妙な技をつかっています。このあたりは、もう少ししっかりと作れば、LINQ と同じになるんでしょうが、しっかり作ってしまうと LINQ と同じになりそうなんで、このあたりで止めておきます。
上記のコードをコンパイルするためのクラス群は以下になります。コンパイルするためだけなので、中身は作っていませんが、まあ、構造が分かるかと。本来はパイプで使うわけだから、グラフィック系のフィルターのようにしたいですよね。ちょっとそのあたりの例は思案中ということで。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | public class DB { private SqlConnection _cn; public string ConnectionString { get ; set ; } public static DB operator |(DB db, string name) { return db; } public static DB operator |(DB db, OP op) { return db; } public static implicit operator RESULT(DB db) { return new RESULT(); } } public static class DPipeExtentions { public static OP EQ( this string cname, object val ) { return new OP { ColumnName = cname, Value= val, OpCode = OP.OPRATOR.EQ }; } public static OP NE( this string cname, object val ) { return new OP { ColumnName = cname, Value= val, OpCode = OP.OPRATOR.NE }; } public static OP LE( this string cname, object val) { return new OP { ColumnName = cname, Value = val, OpCode = OP.OPRATOR.LE }; } public static OP LT( this string cname, object val) { return new OP { ColumnName = cname, Value = val, OpCode = OP.OPRATOR.LT }; } public static OP GE( this string cname, object val) { return new OP { ColumnName = cname, Value = val, OpCode = OP.OPRATOR.GE }; } public static OP GT( this string cname, object val) { return new OP { ColumnName = cname, Value = val, OpCode = OP.OPRATOR.GT }; } } public class OP { public enum OPRATOR { EQ, NE, LT, LE, GT,GE, } public OPRATOR OpCode { get ; set ; } public string ColumnName { get ; set ; } public object Value { get ; set ; } public static OP operator %(OP op, object val) { op.Value = val; return op; } public static implicit operator OP( string name ) { return new OP{ ColumnName = name }; } public static OP operator ==(OP op, object val) { return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.EQ }; } public static OP operator !=(OP op, object val) { return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.NE }; } public static OP operator <(OP op, object val) { return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.LT }; } public static OP operator <=(OP op, object val) { return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.LE }; } public static OP operator >(OP op, object val) { return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.GT }; } public static OP operator >=(OP op, object val) { return new OP { ColumnName = op.ColumnName, Value = val, OpCode = OPRATOR.GE }; } public override bool Equals( object obj) { return base .Equals(obj); } public override int GetHashCode() { return base .GetHashCode(); } } public class RESULT : List< object > { } public class EQ : OP { public static implicit operator EQ( string name) { return (EQ) new OP { ColumnName = name, OpCode = OPRATOR.EQ }; } } public class UP : OP { public static implicit operator UP( string name) { return (UP) new OP { ColumnName = name, OpCode = OPRATOR.GE }; } } |