2012/08/19

C#.NETで覚えたことJavaと比較しつつ忘備録

Webアクセス

とても簡単。System.Net.WebClientを使うだけ。jakartaのHttpClient相当。
  • http://msdn.microsoft.com/ja-jp/library/system.net.webclient.aspx

    文字コードを自動判定するDownloadString()はバグっているらしいので自力で文字コード処理が必要。

  • http://bluewatersoft.cocolog-nifty.com/blog/2011/08/net-webclient-e.html

    using System.Net; static string getWebData(string url) { WebClient wc = new System.Net(); byte[] data = wc.DownloadData(url); Encoding enc = Encoding.GetEncoding("utf-8"); return enc.GetString(data); }

    XMLとXPath

    System.Xmlに一通りそろっている。

    http://msdn.microsoft.com/ja-jp/library/gg145036

    クラス名の頭にXmlが付くのがウザイかも。
    その他は普通にDOMな感じ。

    名前空間付きのXPath処理でちゃんとリゾラバ用意しないといけない。
    JavaだとlocalNameだけでも許容してくれたんだが。

    using System.Xml;
    
    static getODataProperty(url) {
    	string xml = getWebData(url);
    	XmlDocument xmlDocument = new XmlDocument();
    	xmlDocument.LoadXml(xml);
    
    	XmlNamespaceManager resolver = new XmlNamespaceManager(xmlDocument.NameTable);
    	resolver.AddNamespace("ns", "http://www.w3.org/2005/Atom");
    	resolver.AddNamespace("m", "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata");
    	resolver.AddNamespace("d", "http://schemas.microsoft.com/ado/2007/08/dataservices");
    
    	XmlNodeList nodeList = xmlDocument.SelectNodes("/ns:entry/ns:content/m:properties/d:Name", resolver);
    	if (nodeList.Count == 0) return null;
    	return nodeList[0].InnerText;
    }
    

    文字列定数

    最初なんじゃこれ?と思った @ 付きの文字列定数。here string と言うらしい。 「\」や改行をそのまま文字列内に書ける。

    使ってみると便利。Javaにも欲しいかも。

    string fileName = @"c:\temp\test.log"; string sql = @" SELECT * FROM table1 WHERE a=1 OERDER b ASC ";

    Windowsではファイル名指定で必須だったんだろう。
    Javaでも正規表現を書くときに欲しいのでJDK1.8で取り入れてくれないだろうか。

    App.config

    単純にシステムプロパティなんだけど外部ファイルになっていてファイル名の決まりがあるのは便利。
    Javaの場合、アプリ毎にプロパティファイルが違うので標準化してもいいと思うんだが。

    正規表現

    System.Text.RegularExpressions.Regexから普通に使える。
    JavaのStringに直接正規表現を使えるのは最初どうかと思ったのだがこう見ると便利だね。

    using System.Text.RegularExpressions; string fileNameCs = Regex.Replace(fileName, @"\.java$", ".cs");

    setter/getter

    JavaのBeanはpublicフィールドでいいじゃね?と常々思っていたので プロパティの考え方は有りだとは思うのだが代入演算で副作用が発生するのは 発見困難なバグを作り出しそうで気持ち悪い。

    設計の問題で言語仕様上はできても良いとは思うのだが必ずやるやつがいるんだよね。 まあ演算子のオーバライド全般に言えるんだけど。

    class Hoge { public string Name {set;get;} private int id; public int Id { get { return this.id; } set { this.id = value; } } }

    初期化でthisが使えない

    クラスフィールドの初期化でthisが参照できないのは不便すぎる何とかしてくれ。

    class Hoge { private Foo foo = new Foo(this); // <- thisは使えませんエラー public Hoge() { this.foo = new Foo(this); // <- こっちはOK } }

    雑感

    似てるようでいて思想の違いを感じるねJavaとC#って。
    どっちが良いっていうのは無くて慣れてるほう使えばって感じかな。

    でも、名前の1文字目が大文字は気持ち悪いよ!


  • 2012/08/12

    C#.NETでSQL

    Java 案件に投入されたはずがいつのまにか C#.NET 案件にすり代わっていたでござるよ。*゚д゚)エエェェ

    C# なんて10年くらい前にチョコっとやったことが有るくらい。
    まだ .NET でも無かったし。

    と言うわけで納期は目の前にもかかわらず C#.NET で SQL の使い方とか基本的なとこからお勉強。
    間に合うのかね ┐(´ー`)┌

    とりあえずテーブルに挿入して自動採番された ID を取得するとこまでググって整理してみた。

    using System.Data; using System.Data.SqlClient; { string url = @"Server=.\SQLEXPRESS;database=<database>;uid=<user>;pwd=<pass>"; SqlConnection db = new SqlConnection(url); db.Open(); SqlTransaction tx = db.BeginTransaction(IsolationLevel.Serializable); string sql = "INSERT INTO tblTEST(text1,text2)" + " VALUES (@text1,@text2);" + "SELECT @id = IDENT_CURRENT('tblTEST')"; SqlCommand cmd = new SqlCommand(sql, db, tx); cmd.Parameters.Add("@text1", SqlDbType.VarChar, 10).Value = "text1"; cmd.Parameters.Add("@text2", SqlDbType.VarChar, 10).Value = "text2"; cmd.Parameters.Add("@id", SqlDbType.Int).Direction = ParameterDirection.Output; int newId = cmd.Parameters["@id"].Value; tx.Commit(); db.Close(); }

    一応、動いた。 あれ? PHP+SQLServerでやった時は OUTPUT とかって機能が有ったはずなんだよね..

    調べたら SQLServer/2005 以降には OUTPUT が有る。
    けど C#.NET 用のサンプルが見当たらない...

    勘でいじくってみた。

    using System.Data; using System.Data.SqlClient; { string url = @"Server=.\SQLEXPRESS;database=<database>;uid=<user>;pwd=<pass>"; SqlConnection db = new SqlConnection(url); db.Open(); SqlTransaction tx = db.BeginTransaction(IsolationLevel.Serializable); string sql = @"INSERT INTO tblTEST(text1,text2)" + " OUTPUT INSERTED.id" + " VALUES (@text1,@text2);" SqlCommand cmd = new SqlCommand(sql, db, tx); cmd.Parameters.Add("@text1", SqlDbType.VarChar, 10).Value = "text1"; cmd.Parameters.Add("@text2", SqlDbType.VarChar, 10).Value = "text2"; SqlDataAdapter adapter = new SqlDataAdapter(); DataSet dataSet = new DataSet(); adapter.SelectCommand = cmd; adapter.Fill(dataSet); int newId = (int)dataSet.Tables[0].Rows[0][0]; tx.Commit(); db.Close(); }

    これでも動いた。
    SELECT の結果の受け方が分かりづらいね C#.NET は。

    発行されるSQLが1回で済む後述の方が正解なんだろう。
    先は長そう...



    プロフィール
    20年勤めた会社がリーマンショックで消滅、紆余曲折を経て現在はフリーランスのSE。 失業をきっかけにこのブログを始める。

    サイト内検索

    登録
    RSS/2.0

    カテゴリ

    最近の投稿【C#】

    リンク

    アーカイブ