探してみたら
ObjectDataSourceにPrivateで持っているDataTableに
ポップアップダイアログでリストを出して選択した行の中身を
メモリ上で追加するというのもありました。
知識がなくなかなか作れず標準でこのくらいは欲しいなと思いました。
みなさんありがとうございました。
探してみたら
ObjectDataSourceにPrivateで持っているDataTableに
ポップアップダイアログでリストを出して選択した行の中身を
メモリ上で追加するというのもありました。
知識がなくなかなか作れず標準でこのくらいは欲しいなと思いました。
みなさんありがとうございました。
island_town さんからの引用 | |
|
island_town さんがご希望の処理は,恐らく Reflection を使用すれば (Microsoftではなく) 開発者側で実装可能なもののように見えます.詳しい仕様は拝見していませんが,慣れた人なら 3 分ぐらいで作ってしまいそうな気がします.
island_town さんの近辺で,この処理が何度も行われるのであれば,そういうメソッドを作成してみてはいかがでしょうか?
どのように実装するかについて疑問点がございましたら,改めてその点について (適切なフォーラムに) スレッドを立てていただければ,恐らく皆さん協力していただけると思いますよ.
island_town さんからの引用 | |
|
テーブル設計が良くないという印象ですね。
処理として存在するにしても、ExecuteNonQuery メソッドでやると思います。
私は申請されたものが承認された時に
申請用テーブルからマスタテーブルにデータをコピーする時
必要になります。
比較的よくある処理だと思うのですが。
大前提として、.NET Framework クラブ ライブラリは、多くの人がフレームワークとして利用するものという立場があります。
利用率が少ない機能を追加されまくられると、返って完成度が下がります。
利用率の少ないものは自前で作ってもらう、そのためにカスタム コントロールなる概念があります。
ということで、どんな場面に使用できるのかや、用意されることによるメリットを書かないと提案にはならないと思います。
# 本当に必要であれば、すでに誰かが公開 | フィードバックしてそうですね。
しかしフィールド数が多いため
1つ1つ入れていく方法ではコード量が多くなり
NullチェックのIf文もいちいちかませて
同じコードをずらっと並べて
代入文の左右やIf文のフィールドプロパティが一致してるかチェックして
フィールドコピー文の漏れがないか走らせてチェックするという作業が大変なのです。
実際には以下のコードになります。
if(ADataRow.IsAAANull())
BDataRow.SetAAANull();
else
BDataRow.AAA = ADataRow.AAA;
フィールドプロパティの繰り返しが多く、どこかを間違えてしまいやすいです。
フィールド名がコンパイル対象にならないというのであれば
フィールド名を型付データセットのstaticフィールドにして欲しいです。
island_town さんからの引用 | |
|
本当に初心者に優しいと思いますか?私は、学ぶチャンスをつみ取っていると思います。それは優しさではないと考えます。
あるいは、いつまで初心者でいるのですか?または、いつまでも初心者のままとどまっているつもりですか?
このスレッド、「ブラウザを閉じる時に通知するURLをサーバー側でアプリケーション毎に設定して、閉じる時に通知して欲しい 」、「金額TextBoxのOnblurで自動的にカンマを入れてくれるプロパティがほしい。 」の3つからは、単に探すのが面倒だから、探す手間を惜しむことを「初心者に優しい」と表現しているように感じます。
他の言い方をすると、いきなり「要望」としてあげるようなことではなく、まず「やりたいこと」を実現する手順を考える。手順を実装する手段を考える。この手段について「楽にする方法はないか」と、他の開発者に尋ねる。その方法で納得できなくてはじめて、「要望」としてあげることではないでしょうか。(そういうの、他にも投稿されていますね)
前にも書いたように、パーシャル クラスでキャスト動作をオーバーライドすればいいのではないですか?
[code]
partial class BDataRow
{
public static explicit operator ADataRow(BDataRow b) {
ADataRow a = new ADataRow();
a.ColumnA = b.Column5;
a.ColumnB = b.Column4;
...
return a;
}
}
// 使うとき
BDataRow B = (BDataRow) A; // A は ADataRow のインスタンス
tableB.Rows.Add(B);
[/code]
こんな感じ?使ったことないからわかんないや。
で、「DataRow として入力、または出力して、文字列配列で列名を指定する」というのは却下。そんなの、全然優しくない。バグの温床になるだけ。
列名が変わったのにコードを修正するのを忘れていたら、コンパイルは通ってしまいます。そして実行時にエラーになります。このエラーを訂正する方が、あらかじめ「この列をこの列に入れてね」と宣言するより難しいでしょう。
さらに、そんなにあっちこっちのテーブルにコピー配布しなければならない作り(データベースの設計)自体がおかしいのでは?
このようにすることで、動的解釈ではないのでコンパイル時にミスが検出できるため、配列で列を指定するより安全です。
配列で指定するなら、変換をしようとする箇所で配列を書いてやる必要があります。しかし、キャスト動作にしておけばその必要もありません。
少なくとも配列を指定するために1回はコーディングが必要なので、手間は変わらないと思います。
参考リンク:
変換キーワード (C# リファレンス)
>ADataRow に、Fields で定義されたフィールドがない場合、どうしますか?
ADataRow のそれぞれのフォールドの型が、BDataRow の Fields で定義されたフィールドの型と違う場合、どうしますか?
ADataRow のフォールドの個数と、Fields の個数が違う場合、どうしますか?
そういう場合エラーにするロジックを全て組んで標準メソッドとして提供して
初心者が簡単に使えるようにして欲しいのです。
island_town さんからの引用 | |
|
まず、「型付き DataRow」の意味が理解できていないように思います。
あなたがしようとしているのは、単なる「コピー」ではなく、「キャスト」(型変換)動作を含みます。ユーザ定義型からユーザ定義型へのキャストは、開発者が定義するものではないでしょうか?
ADataRow に、Fields で定義されたフィールドがない場合、どうしますか?
ADataRow のそれぞれのフォールドの型が、BDataRow の Fields で定義されたフィールドの型と違う場合、どうしますか?
ADataRow のフォールドの個数と、Fields の個数が違う場合、どうしますか?
それらを考えると、一般的なものを用意するのは難しい、あるいは「ItemArray を用意しておくから良きに計らって」とするのは妥当かと思います。
あるいは、パーシャル クラスでそういうメソッドを用意すればいいのではないですか?それをするのが「開発者」だと思いますけど...?
つまりフィールドの順序が違うDaraRow間で
フィールド名を元にコピーしたいのですが
ItemArrayで自動的にそれをやってくれるのですか?
違うテーブルを元に2つの型付きデータセットを作り
一方のテーブルのデータセットから違うテーブルのデータセットにデータを入れたいのです。
例えば
String Fields[] = {"aaa","bbb","ccc"};
ADataRow.CopyColumn(BDataRow,Fields);
とやると
ADataRowのaaa,bbb,cccフィールドのデータがBDataRowのaaa,bbb,cccフィールドにコピーされる
といった感じです。
確かに説明不足でしたね。すみません。
island_town さんからの引用 | |
|
型付きだろうがなんだろうが、Object 配列として取り出せば、型のないものへ放り込めます。そのために、
|
つまり、DataRow1 型が、string, int, int と定義されていて、DataRow2 型が string, int, datetime、DataRow3 型が string, int, int と定義されているとします。ここで、DataTable1.ItemArray を取り出すと、Object[] {string, int, int} という、Object 型の配列が取り出せます。こいつを DataTable2.ItemArray に設定しようとすると、3つめのカラムの型が違いますから、例外が発生します。しかし、この例外が発生することと、あなたがしようとしていることは、関係ないですよね?
なので、ここで3つめを datetime のオブジェクトに入れ替えて、 Object[] {string, int, datetime} の Object 配列に変換してやれば、DataTable2.ItemArray に放り込むことができるわけです。
また、違うデータ型の DataRow3 に対しては、放り込めます。「配列は、列のコレクションと同じサイズと順序に」なっていますから。
もしかして、配列のコレクションと、違うサイズ、順序の DataTableに放り込みたい?
または、同じサイズ、順序にあわせるのが面倒だと?
それは、要望ではなく、無謀とか、我が儘というものかと。。。
あるいは、「配列を指定して」というのを、もっと具体的に示していただけないでしょうか。
どんな DataRow からどんな DataRow へ、どのような指定をすると、どのようにコピーされる、と。
あなたの頭にあるイメージを、具体的な例示なしに理解できる人はいないと思いますよ。
それだと同じ型付きDataRow間で全部のデータをコピーしてしまいますよね。
違う型付きDataRow間で一部のフィールドだけをデータコピーしたいのです。
違う型付きデータセット間でデータのコピーをする必要が頻繁に発生するのですが
ひとつひとつフィールドをコピーするのが面倒です。
コピーするフィールドの配列を指定してDataRow間のデータのコピーが簡単にできるようにしてほしいです。
なんとなく、要望の背景がわかってきたような気がする。
どっちかというと、「DBNull の時に特別な処理をしなければならない」ほうがメインではないですか?
とはいえ、データベース システムにとって NULL は特殊な意味を持ちますから、「他の何かと同等に扱える」のは、混乱のもとだとも思います。特に、初心者にさせてはいけないことだと思います。VARCHAR に限っては、DBMS によって「空文字列は NULL と同等」と扱うものもあるので、NullValue が有るのかもしれませんね。
なんにしても、NULL を、「Column = NULL」では検査できません。NULL に何かを足しても NULL のままです。ORDER するのに NULL は制御できません。このように、DBMS で NULL の扱いが特殊なので、DBNull を特殊だと意識づける必要があると思います。
で。こういうまとめを、読み手にさせるのはどうかと思うのです。
(そういうことをやってるから MVP なのですが)
他にも、「ご要望の背景をお教え下さい」と、開発統括部からお願いされているものがありますよね。
これは、問題の背景、根本となる原因を探っているわけです。
良い喩えではありませんが。
先日、事務所でダニ、ノミが大量発生しました。とりあえず、殺虫剤を撒いたのですが、おさまりません。さて、どうしますか?
island_townさんの要望は、「強力な殺虫剤を作ってください」と喩えることができると思います。それに対して、「ダニやノミが発生している原因はなんですか?その発生源を取り除くことができませんか?」と、問うています。
ちなみに、屋根裏に鳩が巣を作っていることが原因でした。巣を取り除き、入ってくる隙間を埋めて解決です。要望である「殺虫剤を作ること」は満足していませんが、その要望のもとである「ダニ、ノミを取り除く」ことは満足しています。
そういえば
ADataRow["aaa"] = BDataRow["aaa"];
と書くこともできますが
フィールド名が文字列になってしまうので
型付データセットにフィールド名用クラスを追加して
フィールド名を定義してコンパイル対象にして欲しいです。
ただやっぱりAllowDBNullのチェックは代入時にして欲しいですね。
[code]
partial class BDataRow
{
public static explicit operator ADataRow(BDataRow b) {
ADataRow a = new ADataRow();
Object[] arrB = b.ItemArray;
a.ItemArray = new Object[] {arrBb[1], arrBb[3], ... };
return a;
}
}
提案はありがたいのですが
配列のindexで指定してはどのフィールドをコピーしているのか分からなくなってしまうので困ります。
それともう開発が終わってしまったので
新たにスレッドを立てる気が出ません。
すみません。
申し訳ありませんが、探したり試す手間を惜しんでいるだけのように思えます。
または、いきなり「要望」としてあげることではないと思います。事前に「良い知恵はないでしょうか」と、他のフォーラムで質問した上で、「このスレッドのようになりましたが、それでもやっぱり簡単にできないですか?」と尋ねるという方法が良いと思います。
他のところで書きましたが、
我々が行う提案は、日本でまとめられた後、アメリカへ行きます。日本の開発チームは、アメリカの開発チームを説得しなければなりません。そのため我々は、日本の開発チームを説得する必要があります。日本の開発チームがアメリカの開発チームに説明するために、英語に直しやすい書き方がされているとベターです。
ところで、私が一つ一つ代入するコードを書いたからといって、あなたも代入でコーディングする必要はないですよね?ItemArray で、null の所はどうなりますか?DataSet デザイナから生成されたコードは、プロパティによるアクセス メソッドで例外を送出するようにコーディングされています。このことから、ItemArray で指定した場合はそのまま通るのではないですか?
または、コード上のテーブルと、DBMS 上のテーブルが一致している必要もありません。申請から持ってきて、マスタに書き出してもいいのではないですか?
[code]
partial class BDataRow
{
public static explicit operator ADataRow(BDataRow b) {
ADataRow a = new ADataRow();
Object[] arrB = b.ItemArray;
a.ItemArray = new Object[] {arrBb[1], arrBb[3], ... };
return a;
}
}
[/code]
探してみたら
ObjectDataSourceにPrivateで持っているDataTableに
ポップアップダイアログでリストを出して選択した行の中身を
メモリ上で追加するというのもありました。
知識がなくなかなか作れず標準でこのくらいは欲しいなと思いました。
みなさんありがとうございました。
island_town さんからの引用 | |
|
island_town さんがご希望の処理は,恐らく Reflection を使用すれば (Microsoftではなく) 開発者側で実装可能なもののように見えます.詳しい仕様は拝見していませんが,慣れた人なら 3 分ぐらいで作ってしまいそうな気がします.
island_town さんの近辺で,この処理が何度も行われるのであれば,そういうメソッドを作成してみてはいかがでしょうか?
どのように実装するかについて疑問点がございましたら,改めてその点について (適切なフォーラムに) スレッドを立てていただければ,恐らく皆さん協力していただけると思いますよ.