2007年11月29日

(int)i.Attribute("price")って何?

   このエントリーをはてなブックマークに追加 Clip to Evernote
Visual Studio 2008 ベータに添付されているサンプルコードを眺めていたら、
こんなコードがあった。
string xml = "<order>" +
"<item price='150'>Motor</item>" +
"<item price='50'>Cable</item>" +
"<item price='50'>Modem</item>" +
"<item price='250'>Monitor</item>" +
"<item price='10'>Mouse</item>" +
"</order>";
XElement order = XElement.Parse(xml);
var query = from i in order.Elements("item")
where (int)i.Attribute("price") > 100
select i;

えっ、
(int)i.Attribute("price")

って何?なんでキャストできるの?
C#3.0では、文字列を int にキャストできるようになったのかと思ってしまった。
もちろん、そんなことはない。
 (int)"123";

みたいなコードはコンパイルエラーだ。

調べてみたら、Attribute("price") は、XAttribute型で、その中で、
public static explicit operator int(XAttribute attribute);

とexplicitを使ってキャストを可能にしているのでした。  

Posted by gushwell at 21:56Comments(0)TrackBack(0)

2007年11月26日

C#3.0:Linqでストアドプロシージャの結果をDataGridViewに表示する。

   このエントリーをはてなブックマークに追加 Clip to Evernote
11月21日のい投稿で、LINQ to SQL を使い、WindowsFormsのDataGridViewにストアドプロシージャの結果を表示するには、ToList()メソッドが必要だと書いた。
これについてもうすこし考えて見tる。

C#3.0で導入されたクエリ式の戻り値の型は、System.Linq.IQueryable。
一方、DataContext経由でストアドプロシージャを呼び出した場合は、戻り値は、System.Data.Linq.ISingleResult となっている。

DataGridViewに表示される、表示されないは、この違いだと思われる。
ということは、DataGridView.DataSOurceが受け取る有効な型に、IQueryable が追加されているってことだろうか?
MSDNライブラリを見てもよくわからない。
  
Posted by gushwell at 20:16Comments(2)TrackBack(0)

2007年11月24日

「C#プログラミングレッスン」.NET Framework基礎編

   このエントリーをはてなブックマークに追加 Clip to Evernote
Gushwell's C# Programing Page --「窓際プログラマーの独り言」別館で、メールマガジン『C#プログラミングレッスン』のバックナンバー「.NET Framework基礎編」をダウンロードできるようにしました。

StringBuilder, ArrayList, HashTable, Array, Enum, Math クラスなどについて説明しいます。
  
Posted by gushwell at 14:51Comments(0)TrackBack(0)

2007年11月21日

C#3.0:LINQ to SQLの結果をDataGridViewに表示

   このエントリーをはてなブックマークに追加 Clip to Evernote
LINQ to SQL を使い、WindowsFormsのDataGridViewにストアドプロシージャの結果を表示しようとして、

var db = new NorthwndDataContext();
dataGridView1.DataSource = db.CustOrderHist("ALFKI");

としても、DataGridViewに何も表示されない。

var db = new NorthwndDataContext();
dataGridView1.DataSource = db.CustOrderHist("ALFKI").ToList();

と明示的に、IListに変換してあげる必要がある。
  
Posted by gushwell at 20:58Comments(0)TrackBack(0)

2007年11月20日

LINQ:エンティティクラス名の単数形化

   このエントリーをはてなブックマークに追加 Clip to Evernote
先日、LINQ to SQLのクラスデザイナー画面で作成したエンティティクラスの名前が、複数形から単数形にならないということを書きましたが、単数形にする方法を会社の後輩に教えてもらいました。

複数形のテーブル名から単数形のクラス名に変換する方法

[ツール]-[オプション]-[データベースツール]-[O/Rデザイナ]-[名前の複数形化]で
「有効」プロパティがデフォルトでは、falseになっています。
これを、 trueにすれば、複数形ー>単数形の変更をツールがやってくれます。

なお、ExpressEditionでは、このオプションの設定項目が存在しません。
「単数形にする」がデフォルトで有効になっているようです。

そういえば、英語版の提供が始まったみたいですね。正式版ではどうなっているのかな?

11/21 追記
実は、この質問を、ScottGuさんのブログを翻訳してくださっているChicaさん経由で、ScottGuさんにしていただきました。Chicaさんありがとうございます、

その回答では、やはり、設定を変更することで対応してくらさいとのことでした。
Chicaさんには、もう少し調べてから質問してくださいとお叱りの言葉をいただきました。ほんとそのとおりだと思います。反省です。m(_ _)m

なお、正式版(英語版)をインストールし、オプションを確認してみました。
やはり、[名前の複数形化]は、初期値は falseになっていました。
  
Posted by gushwell at 20:21Comments(0)TrackBack(0)

2007年11月19日

C#3.0:ArrayListに対して Linq を使う

   このエントリーをはてなブックマークに追加 Clip to Evernote
ArrayListに対して Linq を使う。

ArrayList a = new ArrayList();
a.Add(1);
a.Add(2);
a.Add("Microsoft");
a.Add(4);
a.Add("IBM");
a.Add(5);
a.Add("Apple");

というArrayListのインスタンスに対して、

foreach (var x in a.Where(n => n is string))  // コンパイルエラー
Console.WriteLine(x);

※これは、ArrayListから、文字列だけを抜き出そうとしているコード

と書くことができない。
しかし、OfType演算子を使えば、ArrayListをIEnumerable に変換してくれます。
こんな感じ。

IEnumerable<object> oa = a.OfType<object>();
foreach (var x in oa.Where(n => n is string))
Console.WriteLine(x);

さらに便利なのは、OfType は型引数に互換のないメンバーを除外してくれます。つ
まり、stringを指定すれば、フィルタリング機能が働き、string以外を除外できます。
なので、上の例は、

IEnumerable<string> oa = a.OfType<string>();
foreach (var x in oa)
Console.WriteLine(x);

と同じです。

当然ですが、IEnumerable に変換されているので、

IEnumerable<string> oa = a.OfType<string>();
foreach (var x in oa.Where(s => s.Length > 3))
Console.WriteLine(x);

や、

IEnumerable<string> oa = a.OfType<string>();
var r = from s in oa
where s.Length > 3
select s;
foreach (var x in r)
Console.WriteLine(x);

と書くこともできます。  
Posted by gushwell at 20:56Comments(0)TrackBack(0)

2007年11月17日

VS2008 日本語版と英語版で動作が異なる。

   このエントリーをはてなブックマークに追加 Clip to Evernote
Linq to SQL を使っていたら、英語版と日本語版で、動作が異なる点を発見しました。

●現象
LINQ to SQL クラスを作成し、そのデザイナー画面に Northwnd データベースの
Customers, Orders テーブルをD&Dします。

英語版では、作成されるエンティティクラス名は、Customer, Order と単数形
になっています。
日本語版では、Customers, Ordersのままです。

Microsoft Visual C# 2008 Express Edition(英語版)  Version 9.0.20706.1 Beta2  
SQLtoLINQ英語


Microsoft Visual Studio 2008 (日本語版)  Version 9.0.20706.1.Beta2

SQLtoLINQ日本語

日本語版も、英語版と同じような動きになってほしいです。
一応、フィードバックを出しておきました。

11/21 追記
こちらには顛末を書きました。
しかし、マイクロソフト社からは何の音沙汰もありません。まあ、解決したから良いけど。

  
Posted by gushwell at 10:44Comments(0)TrackBack(0)

2007年11月15日

C#3.0: 匿名クラスの日本語名フィールド

   このエントリーをはてなブックマークに追加 Clip to Evernote
僕は、C#のソースコードに日本語識別名を使わない主義だが、
C#3.0では、例外を設けても良いかなと思い始めている。
それは、以下のようなコード。

var db = new NorthwndDataContext();
var products =
from p in db.Product
where p.Category.CategoryName.StartsWith("be")
select new {
ID = p.CategoryID,
Name = p.ProductName,
NumOrders = p.Order_Details.Count,
Revenue = p.Order_Details.Sum(o => o.UnitPrice * o.Quantity)
};
dataGridView1.DataSource = products;

ここで、匿名クラスを利用しているが、この匿名クラスに限っては、利用する価値があるかなと思うようになった。
ただし、その場合でも、匿名クラスのメンバー名を、そのままDataGridなどに表示する場合に限りたい。
上記コードを

var db = new NorthwndDataContext();
var products =
from p in db.Product
where p.Category.CategoryName.StartsWith("be")
select new {
番号 = p.CategoryID,
商品名 = p.ProductName,
注文数 = p.Order_Details.Count,
収入  = p.Order_Details.Sum(o => o.UnitPrice * o.Quantity)
};
dataGridView1.DataSource = products;

とすれば、グリッドのタイトル行を日本語で表示させることが可能だ。
  
Posted by gushwell at 21:55Comments(0)TrackBack(0)