イントレ。
Tag for "C#"
System.Data.SQLite
別名 ADO.NET 2.0/3.5 Provider for SQLite。
気がついたら1.0.65.0がリリースされていたので更新しました。
更新前は1.0.60.0。
…はいいんですが、更新してから挙動が違ってて例外エラーに見舞われることに。
主立った物。
・BeginTransaction()でトランザクション中、Commit時に「SQL error: cannot commit - no transaction is active」
・SELECT文の結果、存在しない項目をExecuteScaler()で読み取るとnullやDBNullが返ってこない
SQLite側の方が問題なのかSystem.Data.SQLite側が問題かわからないけど、
よくわからなかったので、BeginTransaction ()とExecuteScaler()を使わないようにしてみた。
下手にADO.NETラッパーを使う方でSQLiteの操作を覚えちゃったので、
SQLiteのAPI直叩き出来ずSystem.Data.SQLite以外は使えないという罠w
おかげでSQLiteとの情報も多少違ってきているし。
相変わらず茨の道を選んで通ってる気がするよ。
別名 ADO.NET 2.0/3.5 Provider for SQLite。
気がついたら1.0.65.0がリリースされていたので更新しました。
更新前は1.0.60.0。
…はいいんですが、更新してから挙動が違ってて例外エラーに見舞われることに。
主立った物。
・BeginTransaction()でトランザクション中、Commit時に「SQL error: cannot commit - no transaction is active」
・SELECT文の結果、存在しない項目をExecuteScaler()で読み取るとnullやDBNullが返ってこない
SQLite側の方が問題なのかSystem.Data.SQLite側が問題かわからないけど、
よくわからなかったので、BeginTransaction ()とExecuteScaler()を使わないようにしてみた。
下手にADO.NETラッパーを使う方でSQLiteの操作を覚えちゃったので、
SQLiteのAPI直叩き出来ずSystem.Data.SQLite以外は使えないという罠w
おかげでSQLiteとの情報も多少違ってきているし。
相変わらず茨の道を選んで通ってる気がするよ。
SQLiteが.NETに移植された
C#-SQLite
ということでSQLite3.6.16ベースでC#にポーティングされたそうです。
自分も実装の研究としてやってみようかと思った時期があったんですが以下略。
現在の実装がベタ移植らしくパフォーマンスが優れないそうですが、これから改善していくみたいです。
自分は普段System.Data.SQLiteを使っているんですが、
これはSQLite本体を取り込んでいるか、外部DLLから読み込むという実装になっています。
C#-SQLiteはベタ移植だけに互換性は完璧みたいなので、
System.Data.SQLiteのモジュール部を差し替えてpure-managed実装にするのも簡単そうですね。
速度的な問題からまだ選択肢にはなり得ないかもしれませんが。
C#-SQLiteのベストな利用方法はSilverlightで使うことと記事にあるけど、
XNA環境で使うのも悪くない気がする。
C#-SQLite
ということでSQLite3.6.16ベースでC#にポーティングされたそうです。
自分も実装の研究としてやってみようかと思った時期があったんですが以下略。
現在の実装がベタ移植らしくパフォーマンスが優れないそうですが、これから改善していくみたいです。
自分は普段System.Data.SQLiteを使っているんですが、
これはSQLite本体を取り込んでいるか、外部DLLから読み込むという実装になっています。
C#-SQLiteはベタ移植だけに互換性は完璧みたいなので、
System.Data.SQLiteのモジュール部を差し替えてpure-managed実装にするのも簡単そうですね。
速度的な問題からまだ選択肢にはなり得ないかもしれませんが。
C#-SQLiteのベストな利用方法はSilverlightで使うことと記事にあるけど、
XNA環境で使うのも悪くない気がする。
Vistaから追加されたIO処理の低優先度モードですね。
どうやるんだろうってずーっと思ってたんだけど、
プロセスやスレッドの優先度を指定するのと同じ方法でいいみたい。
具体的にはプロセス単位ならSetPriorityClass()を使い、PROCESS_MODE_BACKGROUND_BEGINを指定。
スレッド単位ならSetThreadPriority()を使い、THREAD_MODE_BACKGROUND_BEGINを指定する。
設定するだけでIO処理が低優先度になる。
BEGINがあるのでENDもあって、そっちを指定すると通常の優先度に戻る。
C#からでもP/Invokeを使って使用することが出来ました。
ちなみに現在のプロセスやスレッドの取得はGetCurrentProcess()やGetCurrentThread()で。
こんなに簡単だったなんて…orz
どうやるんだろうってずーっと思ってたんだけど、
プロセスやスレッドの優先度を指定するのと同じ方法でいいみたい。
具体的にはプロセス単位ならSetPriorityClass()を使い、PROCESS_MODE_BACKGROUND_BEGINを指定。
スレッド単位ならSetThreadPriority()を使い、THREAD_MODE_BACKGROUND_BEGINを指定する。
設定するだけでIO処理が低優先度になる。
BEGINがあるのでENDもあって、そっちを指定すると通常の優先度に戻る。
C#からでもP/Invokeを使って使用することが出来ました。
ちなみに現在のプロセスやスレッドの取得はGetCurrentProcess()やGetCurrentThread()で。
こんなに簡単だったなんて…orz
スマートなアプリケーションアーキテクチャの構築(1)
プロパティの代わりにフィールドを内包したクラスを用意して、
データの検証などのロジックをデータに持たせるとスマートという触れ込み。
この記事を見つけたのは数ヶ月前で、見つけたときは感心はしたものの使いどころがわからず、
頭の中に入れておくか…程度で済ませてしまった。
今は後悔している。
↑を基点にいろいろ弄ってMVVMに適用したのが↓。
[WPF][C#]データに知能を持たせる
readonlyフィールドで保持していたインスタンスを自動プロパティにすることでWPFとのバインディングに対応。
検証ロジックやModel←→ViewModel間のデータ変換をデリゲートで分離。
これだけでも十二分にViewModelの実装が楽になります。
コンストラクタで初期化する部分が多少複雑になるデメリットはありますが…。
しかし。
IEditableObjectを実装し、ViewModel基底クラスにプロパティ初期化ロジックを組み込むことで、
ViewModel単位でBeginEdit/EndEdit/CancelEditの透過的なサポートを実現しています。
要はMVVMの作り方+プロパティをちょっと弄るだけで、
検証ロジックとデータのロールバック動作がサポート出来るようになるということ。
正直、MVVM Tookitに取り込まれてもおかしくないぐらい凄いと思う。
そして、その可能性に気づけなかった自分の応用力のなさに愕然…。
もっと精進しなきゃ。
プロパティの代わりにフィールドを内包したクラスを用意して、
データの検証などのロジックをデータに持たせるとスマートという触れ込み。
この記事を見つけたのは数ヶ月前で、見つけたときは感心はしたものの使いどころがわからず、
頭の中に入れておくか…程度で済ませてしまった。
今は後悔している。
↑を基点にいろいろ弄ってMVVMに適用したのが↓。
[WPF][C#]データに知能を持たせる
readonlyフィールドで保持していたインスタンスを自動プロパティにすることでWPFとのバインディングに対応。
検証ロジックやModel←→ViewModel間のデータ変換をデリゲートで分離。
これだけでも十二分にViewModelの実装が楽になります。
コンストラクタで初期化する部分が多少複雑になるデメリットはありますが…。
しかし。
IEditableObjectを実装し、ViewModel基底クラスにプロパティ初期化ロジックを組み込むことで、
ViewModel単位でBeginEdit/EndEdit/CancelEditの透過的なサポートを実現しています。
要はMVVMの作り方+プロパティをちょっと弄るだけで、
検証ロジックとデータのロールバック動作がサポート出来るようになるということ。
正直、MVVM Tookitに取り込まれてもおかしくないぐらい凄いと思う。
そして、その可能性に気づけなかった自分の応用力のなさに愕然…。
もっと精進しなきゃ。
エクスプローラのツリービューを作ってみたみたくて、SHGetFileInfo()を呼んでいたの話。
表示名を取得したいんだけど、どうしても文字化けする。
…で、ネットで拾ったサンプルと比較していったら、
DllImport属性のCharSetにAutoを指定していたのが原因だった。
ちなみに、P/Invokeの定義はこんな感じ。
CharSet.Autoが指定されているので表示が化けます。
CharSet.Ansiを指定するか、指定を外せば正常になります。
なんでCharSet.Autoを指定していたかというと、自作ライブラリの定義をコピペして書き換えたたからw
シェル系のAPIを扱うときは気をつけなきゃいけませんね…。
というか、むやみに知ったかぶってやらなきゃいいのかw
デフォルトは正義。
表示名を取得したいんだけど、どうしても文字化けする。
…で、ネットで拾ったサンプルと比較していったら、
DllImport属性のCharSetにAutoを指定していたのが原因だった。
ちなみに、P/Invokeの定義はこんな感じ。
CharSet.Autoが指定されているので表示が化けます。
CharSet.Ansiを指定するか、指定を外せば正常になります。
[DllImport("shell32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttribs, out SHFILEINFO psfi, uint cbFileInfo, SHGFI uFlags);
// SHGFI .PIDL指定時用
[DllImport("shell32.dll", CharSet=CharSet.Auto)]
public static extern IntPtr SHGetFileInfo(IntPtr pIDL, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, SHGFI uFlags);
[StructLayout(LayoutKind.Sequential)]
public struct SHFILEINFO
{
public IntPtr hIcon;
public int iIcon;
public uint dwAttributes;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szDisplayName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
public string szTypeName;
}
[Flags]
public enum SHGFI : uint
{
ICON = 0x000000100,
DISPLAYNAME = 0x000000200,
TYPENAME = 0x000000400,
ATTRIBUTES = 0x000000800,
ICONLOCATION = 0x000001000,
EXETYPE = 0x000002000,
SYSICONINDEX = 0x000004000,
LINKOVERLAY = 0x000008000,
SELECTED = 0x000010000,
ATTR_SPECIFIED = 0x000020000,
LARGEICON = 0x000000000,
SMALLICON = 0x000000001,
OPENICON = 0x000000002,
SHELLICONSIZE = 0x000000004,
PIDL = 0x000000008,
USEFILEATTRIBUTES = 0x000000010,
ADDOVERLAYS = 0x000000020,
OVERLAYINDEX = 0x000000040
}
// こんな感じで呼ぶ
SHFILEINFO info;
SHGetFileInfo(filepath, 0, out info, (uint)Marshal.SizeOf(typeof(SHFILEINFO)), SHGFI.DISPLAYNAME);
string name = info.szDisplayName; // 表示名
なんでCharSet.Autoを指定していたかというと、自作ライブラリの定義をコピペして書き換えたたからw
シェル系のAPIを扱うときは気をつけなきゃいけませんね…。
というか、むやみに知ったかぶってやらなきゃいいのかw
デフォルトは正義。
Utilities
- タグ
- カレンダー
- 最近の更新
- Adsense