[ADO.NET] AcceptChangesすると、DataAdapter経由でDBが更新されない
- 2010 6/30
- 投稿者 : flied_onion
AcceptChangesすると、DataAdapter経由でDBが更新されません。
下のコメントをとると、DataRowVersionがNoChangeになるため。
// dr.AcceptChanges();
sda.Update(ds,"Table_1");
カテゴリー : .NET
AcceptChangesすると、DataAdapter経由でDBが更新されません。
下のコメントをとると、DataRowVersionがNoChangeになるため。
// dr.AcceptChanges();
sda.Update(ds,"Table_1");
web.configのcompilationセクションを変更することで、バッチコンパイルを行うファイルの操作が可能な模様
通常、machine.configに設定されているcompilationの設定を継承して、ロードされるため
privatePathであるbinフォルダ内のアセンブリはすべてバッチコンパイルされる。
論理上、webserviceの実行(起動?)に必要なファイルだけバッチコンパイルされるだけでも
(実行時にコストがかかるかもしれないが)実行時にアセンブリがロードされれば実行可能だと考える。
なんで、clearセクションを追加してサービスのアセンブリ、システムアセンブリ(machine.config参照)でやればいいのでは・・・
とりあえずためしにやってみた。
webサービスページは表示可能。
実際に動作するかは不明。
だめなときはビルドに必要だったアセンブリを追加すればいいのかな。とか思いながら。
ポイントはmyParam=のとこと、OnRowUpdatedイベント
『DataAdapter.RowUpdated イベント
これまでに説明した方法に関連して DataAdapter.RowUpdated イベントを使用すると、オプティミスティック同時実行制御違反をアプリケーションに通知できます。RowUpdated は、DataSet から Modified 行の更新を行ったときに発生します。これにより、例外発生時の処理、カスタム エラー情報の追加、再試行ロジックの追加などの特別の処理コードを追加できます。RowUpdatedEventArgs オブジェクトは、テーブルの変更行に対する特定の更新コマンドによって影響された行数が設定された RecordsAffected プロパティを返します。オプティミスティック同時実行制御をテストするように更新コマンドを設定した場合は、オプティミスティック同時実行制御違反の発生時に、RecordsAffected プロパティは値 0 を結果として返します。値が 0 なのはレコードが更新されないためです。この場合、例外がスローされます。RowUpdated イベントを使用すると、発生したイベントを処理したり、UpdateStatus.SkipCurrentRow のような RowUpdatedEventArgs.Status 値を設定することで例外を抑止したりできます。RowUpdated イベントの詳細については、「DataAdapter イベントの使用」を参照してください
』
[C#]
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 |
SqlConnection nwindConn = new SqlConnection("Data Source=localhost;Integrated Security=SSPI;Initial Catalog=northwind"); SqlDataAdapter custDA = new SqlDataAdapter("SELECT CustomerID, CompanyName FROM Customers ORDER BY CustomerID", nwindConn); // The Update command checks for optimistic concurrency violations in the WHERE clause. custDA.UpdateCommand = new SqlCommand("UPDATE Customers (CustomerID, CompanyName) VALUES(@CustomerID, @CompanyName) " + "WHERE CustomerID = @oldCustomerID AND CompanyName = @oldCompanyName", nwindConn); custDA.UpdateCommand.Parameters.Add("@CustomerID", SqlDbType.NChar, 5, "CustomerID"); custDA.UpdateCommand.Parameters.Add("@CompanyName", SqlDbType.NVarChar, 30, "CompanyName"); // Pass the original values to the WHERE clause parameters. SqlParameter myParm; myParm = custDA.UpdateCommand.Parameters.Add("@oldCustomerID", SqlDbType.NChar, 5, "CustomerID"); myParm.SourceVersion = DataRowVersion.Original; myParm = custDA.UpdateCommand.Parameters.Add("@oldCompanyName", SqlDbType.NVarChar, 30, "CompanyName"); myParm.SourceVersion = DataRowVersion.Original; // Add the RowUpdated event handler. custDA.RowUpdated += new SqlRowUpdatedEventHandler(OnRowUpdated); DataSet custDS = new DataSet(); custDA.Fill(custDS, "Customers"); // Modify the DataSet contents. custDA.Update(custDS, "Customers"); foreach (DataRow myRow in custDS.Tables["Customers"].Rows) { if (myRow.HasErrors) Console.WriteLine(myRow[0] + "\n" + myRow.RowError); } protected static void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args) { if (args.RecordsAffected == 0) { args.Row.RowError = "Optimistic Concurrency Violation Encountered"; args.Status = UpdateStatus.SkipCurrentRow; } } |
seeAlso:http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/cpguide/html/cpconoptimisticconcurrency.asp
note:UpdateCommand Original ADO.NET でGoogle
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 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 |
<Window x:Class="anm3d.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="anm3d" x:Name="Window" xml:lang="ja-JP" Width="640" Height="480" xmlns:d="http://schemas.microsoft.com/expression/blend/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Window.Resources> <Storyboard x:Key="Start"> <MediaTimeline RepeatBehavior="Forever" Source="C:\windows\clock.avi" BeginTime="00:00:00" Storyboard.TargetName="MediaElement"/> </Storyboard> <Storyboard RepeatBehavior="Forever" x:Key="Rotate"> <Point3DAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="perspectiveCamera" Storyboard.TargetProperty="(ProjectionCamera.Position)"> <SplinePoint3DKeyFrame KeyTime="00:00:00" Value="0,0,10"/> <SplinePoint3DKeyFrame KeyTime="00:00:02" Value="-4.924,-6.428,5.868"/> <SplinePoint3DKeyFrame KeyTime="00:00:04" Value="-5.404,4.556,7.074"/> <SplinePoint3DKeyFrame KeyTime="00:00:06" Value="8.728,2.922,3.911"/> <SplinePoint3DKeyFrame KeyTime="00:00:08" Value="-7.708,-3.937,5.009"/> <SplinePoint3DKeyFrame KeyTime="00:00:10" Value="0,0,10"/> </Point3DAnimationUsingKeyFrames> <Vector3DAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="perspectiveCamera" Storyboard.TargetProperty="(ProjectionCamera.UpDirection)"> <SplineVector3DKeyFrame KeyTime="00:00:00" Value="0,1,0"/> <SplineVector3DKeyFrame KeyTime="00:00:02" Value="-0.413,0.766,0.492"/> <SplineVector3DKeyFrame KeyTime="00:00:04" Value="-0.801,-0.024,-0.597"/> <SplineVector3DKeyFrame KeyTime="00:00:06" Value="-0.329,-0.243,0.913"/> <SplineVector3DKeyFrame KeyTime="00:00:08" Value="-0.618,0.651,-0.441"/> <SplineVector3DKeyFrame KeyTime="00:00:10" Value="0,1,0"/> </Vector3DAnimationUsingKeyFrames> <Vector3DAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="perspectiveCamera" Storyboard.TargetProperty="(ProjectionCamera.LookDirection)"> <SplineVector3DKeyFrame KeyTime="00:00:00" Value="0,0,-10"/> <SplineVector3DKeyFrame KeyTime="00:00:02" Value="4.924,6.428,-5.868"/> <SplineVector3DKeyFrame KeyTime="00:00:04" Value="5.404,-4.556,-7.074"/> <SplineVector3DKeyFrame KeyTime="00:00:06" Value="-8.728,-2.922,-3.911"/> <SplineVector3DKeyFrame KeyTime="00:00:08" Value="7.708,3.937,-5.009"/> <SplineVector3DKeyFrame KeyTime="00:00:10" Value="0,0,-10"/> </Vector3DAnimationUsingKeyFrames> </Storyboard> </Window.Resources> <Window.Triggers> <EventTrigger RoutedEvent="FrameworkElement.Loaded"> <BeginStoryboard Storyboard="{StaticResource Start}"/> <BeginStoryboard Storyboard="{StaticResource Rotate}"/> </EventTrigger> </Window.Triggers> <Grid x:Name="LayoutRoot"> <Viewport3D x:Name="viewport3D"> <Viewport3D.Camera> <PerspectiveCamera FieldOfView="45" NearPlaneDistance="0.1" FarPlaneDistance="100" Position="0,0,10" LookDirection="0,0,-10" UpDirection="0,1,0" x:Name="perspectiveCamera"/> </Viewport3D.Camera> <ModelVisual3D > <ModelVisual3D.Content> <AmbientLight Color="#FFFFFFFF"/> </ModelVisual3D.Content> <ModelVisual3D.Transform> <Transform3DGroup> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> <ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/> <RotateTransform3D d:EulerAngles="0,0,0"/> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> </Transform3DGroup> </ModelVisual3D.Transform> </ModelVisual3D> <ModelVisual3D x:Name="object3D"> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D> <MeshGeometry3D.Positions> <Point3D>-1,1,1</Point3D> <Point3D>-1,-1,1</Point3D> <Point3D>1,-1,1</Point3D> <Point3D>1,-1,1</Point3D> <Point3D>1,1,1</Point3D> <Point3D>-1,1,1</Point3D> </MeshGeometry3D.Positions> <MeshGeometry3D.Normals> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> </MeshGeometry3D.Normals> <MeshGeometry3D.TextureCoordinates> <Point>0,0</Point> <Point>0,1</Point> <Point>1,1</Point> <Point>1,1</Point> <Point>1,0</Point> <Point>0,0</Point> </MeshGeometry3D.TextureCoordinates> </MeshGeometry3D> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <MaterialGroup> <DiffuseMaterial> <DiffuseMaterial.Brush> <VisualBrush> <VisualBrush.Visual> <MediaElement x:Name="MediaElement"/> </VisualBrush.Visual> </VisualBrush> </DiffuseMaterial.Brush> </DiffuseMaterial> </MaterialGroup> </GeometryModel3D.Material> </GeometryModel3D> </ModelVisual3D.Content> </ModelVisual3D> <ModelVisual3D x:Name="object3D_Copy"> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D> <MeshGeometry3D.Positions> <Point3D>-1,1,1</Point3D> <Point3D>-1,-1,1</Point3D> <Point3D>1,-1,1</Point3D> <Point3D>1,-1,1</Point3D> <Point3D>1,1,1</Point3D> <Point3D>-1,1,1</Point3D> </MeshGeometry3D.Positions> <MeshGeometry3D.Normals> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> </MeshGeometry3D.Normals> <MeshGeometry3D.TextureCoordinates> <Point>0,0</Point> <Point>0,1</Point> <Point>1,1</Point> <Point>1,1</Point> <Point>1,0</Point> <Point>0,0</Point> </MeshGeometry3D.TextureCoordinates> </MeshGeometry3D> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <MaterialGroup> <DiffuseMaterial> <DiffuseMaterial.Brush> <VisualBrush> <VisualBrush.Visual> <TextBox Text="Media"/> </VisualBrush.Visual> </VisualBrush> </DiffuseMaterial.Brush> </DiffuseMaterial> </MaterialGroup> </GeometryModel3D.Material> </GeometryModel3D> </ModelVisual3D.Content> <ModelVisual3D.Transform> <Transform3DGroup> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> <ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/> <RotateTransform3D d:EulerAngles="0,-90,0"> <RotateTransform3D.Rotation> <AxisAngleRotation3D Angle="90" Axis="0,-1,0"/> </RotateTransform3D.Rotation> </RotateTransform3D> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> </Transform3DGroup> </ModelVisual3D.Transform> </ModelVisual3D> <ModelVisual3D x:Name="object3D_Copy2"> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D> <MeshGeometry3D.Positions> <Point3D>-1,1,1</Point3D> <Point3D>-1,-1,1</Point3D> <Point3D>1,-1,1</Point3D> <Point3D>1,-1,1</Point3D> <Point3D>1,1,1</Point3D> <Point3D>-1,1,1</Point3D> </MeshGeometry3D.Positions> <MeshGeometry3D.Normals> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> </MeshGeometry3D.Normals> <MeshGeometry3D.TextureCoordinates> <Point>0,0</Point> <Point>0,1</Point> <Point>1,1</Point> <Point>1,1</Point> <Point>1,0</Point> <Point>0,0</Point> </MeshGeometry3D.TextureCoordinates> </MeshGeometry3D> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <MaterialGroup> <DiffuseMaterial> <DiffuseMaterial.Brush> <VisualBrush> <VisualBrush.Visual> <TextBox Text="Movie"/> </VisualBrush.Visual> </VisualBrush> </DiffuseMaterial.Brush> </DiffuseMaterial> </MaterialGroup> </GeometryModel3D.Material> </GeometryModel3D> </ModelVisual3D.Content> <ModelVisual3D.Transform> <Transform3DGroup> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> <ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/> <RotateTransform3D d:EulerAngles="0,90,0"> <RotateTransform3D.Rotation> <AxisAngleRotation3D Angle="90" Axis="0,1,0"/> </RotateTransform3D.Rotation> </RotateTransform3D> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> </Transform3DGroup> </ModelVisual3D.Transform> </ModelVisual3D> <ModelVisual3D x:Name="object3D_Copy3"> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D> <MeshGeometry3D.Positions> <Point3D>-1,1,1</Point3D> <Point3D>-1,-1,1</Point3D> <Point3D>1,-1,1</Point3D> <Point3D>1,-1,1</Point3D> <Point3D>1,1,1</Point3D> <Point3D>-1,1,1</Point3D> </MeshGeometry3D.Positions> <MeshGeometry3D.Normals> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> </MeshGeometry3D.Normals> <MeshGeometry3D.TextureCoordinates> <Point>0,0</Point> <Point>0,1</Point> <Point>1,1</Point> <Point>1,1</Point> <Point>1,0</Point> <Point>0,0</Point> </MeshGeometry3D.TextureCoordinates> </MeshGeometry3D> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <MaterialGroup> <DiffuseMaterial> <DiffuseMaterial.Brush> <VisualBrush> <VisualBrush.Visual> <TextBox Text="WPF"/> </VisualBrush.Visual> </VisualBrush> </DiffuseMaterial.Brush> </DiffuseMaterial> </MaterialGroup> </GeometryModel3D.Material> </GeometryModel3D> </ModelVisual3D.Content> <ModelVisual3D.Transform> <Transform3DGroup> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> <ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/> <RotateTransform3D d:EulerAngles="-90,0,0"> <RotateTransform3D.Rotation> <AxisAngleRotation3D Angle="90" Axis="-1,0,0"/> </RotateTransform3D.Rotation> </RotateTransform3D> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> </Transform3DGroup> </ModelVisual3D.Transform> </ModelVisual3D> <ModelVisual3D x:Name="object3D_Copy4"> <ModelVisual3D.Content> <GeometryModel3D> <GeometryModel3D.Geometry> <MeshGeometry3D> <MeshGeometry3D.Positions> <Point3D>-1,1,1</Point3D> <Point3D>-1,-1,1</Point3D> <Point3D>1,-1,1</Point3D> <Point3D>1,-1,1</Point3D> <Point3D>1,1,1</Point3D> <Point3D>-1,1,1</Point3D> </MeshGeometry3D.Positions> <MeshGeometry3D.Normals> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> <Vector3D>0,0,1</Vector3D> </MeshGeometry3D.Normals> <MeshGeometry3D.TextureCoordinates> <Point>0,0</Point> <Point>0,1</Point> <Point>1,1</Point> <Point>1,1</Point> <Point>1,0</Point> <Point>0,0</Point> </MeshGeometry3D.TextureCoordinates> </MeshGeometry3D> </GeometryModel3D.Geometry> <GeometryModel3D.Material> <MaterialGroup> <DiffuseMaterial> <DiffuseMaterial.Brush> <VisualBrush> <VisualBrush.Visual> <TextBox Text="Element"/> </VisualBrush.Visual> </VisualBrush> </DiffuseMaterial.Brush> </DiffuseMaterial> </MaterialGroup> </GeometryModel3D.Material> </GeometryModel3D> </ModelVisual3D.Content> <ModelVisual3D.Transform> <Transform3DGroup> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> <ScaleTransform3D ScaleX="1" ScaleY="1" ScaleZ="1"/> <RotateTransform3D d:EulerAngles="90,0,0"> <RotateTransform3D.Rotation> <AxisAngleRotation3D Angle="90" Axis="1,0,0"/> </RotateTransform3D.Rotation> </RotateTransform3D> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> <TranslateTransform3D OffsetX="0" OffsetY="0" OffsetZ="0"/> </Transform3DGroup> </ModelVisual3D.Transform> </ModelVisual3D> </Viewport3D> </Grid> </Window> |
http://www.atmarkit.co.jp/fdotnet/mthread/mthread03/mthread03_01.html
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 |
namespace DataSetUpdateTest { class Program { static void Main(string[] args) { string response; DataSet ds = new System.Data.DataSet(); DataRow dr; DataSet newDs; DataRow[] rowsInError; DataTable newDt; DataColumn newCol; int i; SqlConnection sc = new SqlConnection(); sc.ConnectionString = "Data Source=PD3GCOT\\SQLEXPRESS;User ID=sa;Password=sa;" + "Initial Catalog=mydb;"; SqlDataAdapter sda = new SqlDataAdapter("Select * from Table_1;",sc); SqlCommandBuilder cb = new SqlCommandBuilder(sda); sc.Open(); sda.MissingSchemaAction = MissingSchemaAction.AddWithKey; sda.Fill(ds, "Table_1"); /* ds.EnforceConstraints = true; ds.SchemaSerializationMode = SchemaSerializationMode.IncludeSchema; ds.WriteXmlSchema("c:\\file.xsd"); */ ds.Tables["Table_1"].Rows[0].Delete(); DataRow delRow; if (ds.HasChanges(DataRowState.Deleted)) { newDs = ds.GetChanges(DataRowState.Deleted); if (!newDs.HasErrors) { delRow = newDs.Tables["Table_1"].Rows[0]; dr = ds.Tables["Table_1"].Rows[0]; try { // the following line generates the exception Console.WriteLine(delRow[0]); } catch (Exception e) { Console.WriteLine("01:" + e.Message); } try { Console.WriteLine(delRow[0, DataRowVersion.Original]); } catch (Exception e) { Console.WriteLine("02:" + e.Message); } try { Console.WriteLine(dr[0, DataRowVersion.Original]); } catch (Exception e) { Console.WriteLine("03:" + e.Message); } // dr.AcceptChanges(); //sda.Update(ds,"Table_1"); } else { Console.WriteLine("newDS has Error"); } } else { Console.WriteLine("newDS has no changes"); } if (sc.State == ConnectionState.Open) sc.Close(); sc = null; Console.WriteLine("Update was processed successfulle?"); Console.ReadLine(); } } } |
デバッグのステップインでたまにソースファイルを求められる場合があります。
俺の予想では、デバッグビルドだがpdbファイルがないdll(つーかアセンブリ)の場合に出現。
キャンセルするとそれ以降聞かれなくなりますが、その場合は以下のダイアログボックスで
「以下のソース ファイルを探さない」にソース名がいるやも。
— MSDN
[デバッグ ソース ファイル]
([ソリューション プロパティ ページ] ダイアログ ボックス – [共通プロパティ])参照
デバッグの設定と準備
このプロパティ ページでは、ソリューションのデバッグ時にデバッガによってソース ファイルが検索される場所を指定します。
[デバッグ ソース ファイル] プロパティ ページを開くには、ソリューション エクスプローラでソリューションを右クリックし、ショートカット メニューの [プロパティ] をクリックします。[共通プロパティ] フォルダを展開し、[デバッグ ソース ファイル] ページをクリックします。
[以下のパスからソース ファイルを検索する]
ソリューションのデバッグ時に、デバッガによってソース ファイルが検索されるディレクトリの一覧が表示されます。
[以下のソース ファイルを探さない]
デバッガによる読み取りから除外するファイルの名前を入力できます。デバッガは、上で指定したディレクトリのいずれかでこれらのファイルを見つけた場合、それを無視します。
参照
—–
ms-help://MS.MSDNQTR.2005JAN.1041/vsdebug/html/vxurfDebugSourceFilesCommonPropertiesSolutionPropertyPagesDialogBox.htm
2005のみ?
http://www.jurapun.com/Tutorial/CSharp/Thread.shtml
.NET Frameworkでは、スレッドを使うときThreadクラスとThreadStartデリゲートを使います。ThreadStartデリゲートは、次のように定義されています。
[ComVisibleAttribute(true)] public delegate void ThreadStart();
Threadクラスのコンストラクタは、4つのバージョン(オーバーロード)がありますが、ThreadStartデリゲートを使うバージョンは、
Thread(ThreadStart)
と宣言されています。デリゲートとは、安全な関数ポインタみたいなものなので、ThreadStartにはスレッドとして動作させるメソッドを設定します。
(注意) ThreadStartデリゲートをインスタンス化せずに
Thread th = new Thread(Func);
のように関数名を指定してもかまいません(自動的にデリゲートに変換されます)。
ThreadStartデリゲートの作るには
バックグランドで動作するメソッドの名前を引数としてThreadStartをインスタンス化する。
例 new ThreadStart(DoWork);
バックグランドで動作するメソッドのプロトタイプは、戻り値なし(void型)、引数なしであること。
例 void DoWork();
スレッドを使う手順
ThreadStartデリゲートを引数として、Threadクラスをインスタンス化する。
ThreadクラスのStartメソッドを呼び出す。
結局、次のようなコードを実行するとスレッドが走ります。
Thread thread = new Thread(new ThreadStart(Work));
…………
…………
void Work()
{
….
}
サンプル1
単純なサンプルです。スレッド関数を単に走らせるだけです。
ThreadStartデリゲートの問題点
ThreadStartデリゲートの関数プトロタイプは、
void Function();
という形式なので、パラメータを渡すことができません。これは実用上不便なので普通は、クラスを用意しそのコンストラクタのパラメータとしてスレッドのパラメータを渡します。そして、そのパラメータをThreadStartデリゲートで指定したメソッド(関数)が使用して処理を行うようにします。
サンプル2
スレッド用クラスを用意して、そのメンバ関数をスレッドとして走らせるサンプル
簡単にスレッドを使うためのクラス
スレッドを使うたびに、クラスを作って同じような処理を行うためのコードを書くのは面倒なので、Java風のRunnableという抽象クラスを作って、それをベースとしてスレッド用クラスを作ると便利です。サンプル3は、Runnableクラスとその使用例です。
サンプル3 (Runnable.cs, ThreadTest3.cs)
スレッドを便利に使うためのRunnableクラスを使ったサンプル
ParameterizedThreadStartデリゲートを使う
ParameterizedThreadStartデリゲートは、オブジェクトを引数とする関数を設定できます。ということは、データを直接にスレッドに渡すことができます。
ParameterizedThreadStartデリゲートを使うときの要件
スレッド関数は、void型でパラメータはobject型1個であること。
スレッドの開始は、Threadクラスのvoid Start(object)メソッドを使うこと。このメソッドの引数として、パラメータをスレッド関数に引き渡すことができる。
なお、このデリゲートは.NET Framework 2.0以上で使用できます。
サンプル4
ParameterizedThreadStartデリゲートを利用して、スレッドに直接データを渡して動作させる例。
スレッドの終了を待つには
サンプル1~4までは、スレッドの終了を待たずにMainが終了していました。これでは、すけっどの実行結果の表示やエラーがあったときの処理ができません。スレッドが終わるまで待つには、ThreadクラスのIsAliveプロパティを監視します。監視ループの中では、ThreadクラスのSleepメソッドを使って、メインスレッドをある時間間隔でスリープさせながら監視します。そうしないと、CPUの負荷が高くなって動作が重くなります。
(参考) Joinメソッドを使う方法(下記)も考慮してください。
サンプル5
サンプル4でスレッドの終了を待つようにしたサンプル。
呼び出しもとのスレッドをブロックするには
呼び出しもとで、スレッドの監視をすると無駄なCPUタイムを消費するし、コードも書かなくてはなりません。と言う訳で、Joinメソッドというものが用意されています。これを使うと、サンプル5はサンプル6のように書き換えできます。
サンプル6
サンプル5でjoinメソッドを使ってスレッドの終了を待つようにしたサンプル。
スレッドどうしの競合を回避するには
複数のスレッドが競合するリソースを使うときには、競合を回避する必要があります。例えば、あるスレッドがあるデータを書き換えている最中に、別のスレッドがそのデータを読み出すと困ったことが起こるかもしれません。そのような場合には、そのリソースをロックして、他のスレッドがアクセスできないようにすることができます。
lockキーワードは、次のような感じで使います。
void DoWork() {
……
lock (object1) { // object1は他のスレッドと競合するオブジェクト
…… // 他のスレッドと競合するコード
}
サンプル7
2つのスレッド関数が1つのオブジェクトを使うサンプル。
(参考)
Monitorクラスを使ってスレッドの競合を回避することもできます。lockキーワードはMonitorクラスを使って実装されているそうです。
スレッドどうしで同期を取るには
あるスレッドから別のスレッドへイベントを通知して、複数のスレッドが協調しながらある動作をさせたいときがあります。そのような場合は、AutoResetEventクラスやManualResetEventクラスを使います。
これらのクラスを使うと、スレッドはシグナルを通じて相互に通信できます。AutoResetEventクラスとManualResetEventクラスの違いは、シグナル状態のリセットが自動で行われるのか、手動で行うかです。ManualResetEventは複数のスレッドにシグナルを送るとき使います。
AutoResetEventクラスの使い方
AutoResetEventクラスをインスタンス化する。AutoResetEventコンストラクタは、bool型パラメータで初期のシグナル状態を指定する。
(例) AutoEventReset event1 = new AutoEventReset(false); // 非シグナル状態で初期化
イベント待ち側のスレッドは、WaitOneメソッドを使って、シグナル待ちで待機する。このとき、そのスレッドはブロッキング状態になる。
イベント発信側のスレッドは、発信可能になったらSetメソッドを使ってイベントをシグナル状態にする。
WaitOneメソッドで待機していたスレッドがブロッキングが解除され処理が続行される。
サンプル8
あるスレッドをシグナル待ちにして、別のスレッドがシグナルを送るサンプル
(参考) プロセス間で同期を取るときは、Mutexクラスを使います。
Windowsフォームでのバックグランド処理
Windowsフォームでバックグランド処理をするには、BackgroundWorkerコントロールを使うと簡単です。バックグランド処理は、DoWorkイベントハンドラを追加しその中にバックグランド処理を記述します。バックグランド処理に開始は、RunWorkerAsyncメソッドで開始することができます。
バックグランド処理が終了すると、RunWorkerCompletedイベントが発生するのでその中で後処理を行うことができます。
APIをコールせずに時間がかかる処理を行う場合は、Application.DoEventsメソッドをループ内でコールして、Windowsメッセージポンプを動作させます。そうしないと、Windowsメッセージがリアルタイムで処理されないため、他の操作が阻害されます。
Windowsフォームでスレッドを停止させるには
ApplicationクラスのExit()やExitThread()メソッドを使います。
天文学的な数値を変換しないかぎりはなくてもよさそう。
やるならtypeof(string)で中間キャストするよりも、
typeof(byte[])のほうがいいんじゃないかとも思われる。
typeof(string)の場合、Oracle DATE型の場合に時刻が失われるという事象が発生。
http://otndnld.oracle.co.jp/document/products/oracle10g/101/doc_v6/win.101/B15519-01/featSafeType.htm
VB.NET用のサンプルソース
C#用に書き換えてください。
— App.Config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="Application Name" value="MyApplication" />
</appSettings>
</configuration>
— 読み取りアクセス
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
MessageBox.Show("Application Name = " & _
System.Configuration.ConfigurationSettings.AppSettings("Application Name"))
End Sub
— 書き込みボタン
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim asm As System.Reflection.Assembly = System.Reflection.Assembly.GetExecutingAssembly()
Dim appConfigPath As String
appConfigPath = System.IO.Path.GetDirectoryName(asm.Location) + "\Config.exe.config"
Dim doc As System.Xml.XmlDocument = New System.Xml.XmlDocument
doc.Load(appConfigPath)
Dim node As System.Xml.XmlNode = doc("configuration")("appSettings")
Dim n As System.Xml.XmlNode
For Each n In doc("configuration")("appSettings")
If n.Name = "add" Then
If n.Attributes.GetNamedItem("key").Value = "Application Name" Then
n.Attributes.GetNamedItem("value").Value = Me.Text
End If
End If
Next
Dim newNode As System.Xml.XmlElement = doc.CreateElement("add")
newNode.SetAttribute("key", "Form Size")
newNode.SetAttribute("value", Me.Width & "," & Me.Height)
node.AppendChild(newNode)
doc.Save(appConfigPath)
End Sub
How To Get Current ColumnHeader
/// <summary>
/// 現在表示されている DataGridTableStyle を確認するには、
/// System.Windows.Forms.DataGrid の DataSource プロパティと
/// DataMember プロパティを使用して、CurrencyManager を返します。
/// データ ソースに ITypedList インターフェイスが実装されている場合は、
/// GetListName メソッドを使用すると、現在のテーブルの MappingName を返すことができます。
/// 上記の例を次の C# コードに示します。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void saveColumnNameClipboardButton_Click(object sender, System.EventArgs e)
{
CurrencyManager myCM = (CurrencyManager)
BindingContext[dataGrid1.DataSource, dataGrid1.DataMember];
IList myList = myCM.List;
ITypedList thisList = (ITypedList) myList;
MessageBox.Show(thisList.GetListName(null));
PropertyDescriptorCollection pdc = thisList.GetItemProperties(null);
string s = "";
foreach(PropertyDescriptor pd in pdc)
{
s +=pd.Name + " // ";
}
MessageBox.Show(s);
}
まずクラスライブラリなどを作成するときにXMLドキュメントも生成します。
参照設定するdllと同じ場所にxmlファイルも置いておく。
なお、コマンドラインコンパイルの場合は/doc:hogehoge.xml オプションを利用する。
ms-help://MS.VSCC/MS.MSDNVS.1041/cscomp/html/vcerrDocProcessDocumentationComments.htm
ms-help://MS.VSCC/MS.MSDNVS.1041/csref/html/vcwlkXMLDocumentationTutorial.htm
VisualStudio Visual Studio RegularExpression 正規表現 検索 置換
{}はマッチ数の範囲ではなく、タグつき正規表現となる。
[A-Z]{4}
としたい場合は
[A-Z]^4
と記述する。
[A-Z]{4,5}などに変わる記述があるかどうかは不明
see also
http://msdn2.microsoft.com/ja-jp/library/2k3te2cs.aspx
Application.ThreadException +=new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=30513&forum=7&6
http://www.ailight.jp/blog/kazuk/articles/6287.aspx
http://www.atmarkit.co.jp/fdotnet/special/java2cs/java2cs_02.html
http://msdn2.microsoft.com/ja-jp/library/ms173178.aspx
http://msdn2.microsoft.com/ja-jp/library/kbbwt18a.aspx
DataAdapter によるバッチ更新の実行
以前のバージョンの ADO.NET では、DataSet に格納されている変更内容をデータベースに反映する場合、DataAdapter の Update メソッドを実行して、1 行ずつデータベースを更新していました。このメソッドは、指定された DataTable 内の行を反復処理すると、各 DataRow を調べ、行が変更されたことを確認します。行が変更されている場合、その行の RowState プロパティの値に基づいて、適切な UpdateCommand、InsertCommand、または DeleteCommand のいずれかを呼び出します。各行の更新では、データベースへのネットワーク ラウンドトリップが発生します。
ADO.NET 2.0 では、UpdateBatchSize プロパティが DataAdapter によって公開されます。UpdateBatchSize を正の整数値に設定すると、データベースの更新が指定されたサイズのバッチとして送信されます。たとえば、UpdateBatchSize を 10 に設定すると、10 個の個別のステートメントがグループ化され、単一のバッチとして送信されます。UpdateBatchSize を 0 に設定すると、DataAdapter は、サーバーが処理できる最大のバッチ サイズを使用します。1 に設定すると、バッチ更新が無効になり、1 行ずつ送信されます。
サイズの大きいバッチを実行すると、パフォーマンスが低下する可能性があります。そのため、アプリケーションを実装する前に、バッチの最適なサイズ設定をテストする必要があります。
UpdateBatchSize プロパティの使用
バッチ更新を有効にする場合、DataAdapter の UpdateCommand、InsertCommand および DeleteCommand の UpdatedRowSource プロパティ値を、None または OutputParameters に設定する必要があります。バッチ更新を実行する際、FirstReturnedRecord または Both のコマンドの UpdatedRowSource プロパティ値は、無効になります。
UpdateBatchSize プロパティを使用するプロシージャを次に示します。このプロシージャは、2 つの引数を取ります。1 つは、Production.ProductCategory テーブル内の ProductCategoryID フィールドおよび Name フィールドを表す列を持つ DataSet オブジェクトで、もう 1 つは、バッチ サイズ (バッチ ファイル内の行数) を表す整数です。このコードにより、新しい SqlDataAdapter オブジェクトが作成され、その UpdateCommand、InsertCommand プロパティおよび DeleteCommand プロパティが設定されます。このコードは、DataSet オブジェクトによって行が変更済みになっていることを前提としています。このオブジェクトは、UpdateBatchSize プロパティを設定し、更新を実行します。
{C#}
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 |
public static void BatchUpdate(DataTable dataTable,Int32 batchSize) { // Assumes GetConnectionString() returns a valid connection string. string connectionString = GetConnectionString(); // Connect to the AdventureWorks database. using (SqlConnection connection = new SqlConnection(connectionString)) { // Create a SqlDataAdapter. SqlDataAdapter adapter = new SqlDataAdapter(); // Set the UPDATE command and parameters. adapter.UpdateCommand = new SqlCommand( "UPDATE Production.ProductCategory SET " + "Name=@Name WHERE ProductCategoryID=@ProdCatID;", connection); adapter.UpdateCommand.Parameters.Add("@Name", SqlDbType.NVarChar, 50, "Name"); adapter.UpdateCommand.Parameters.Add("@ProdCatID", SqlDbType.Int, 4, "ProductCategoryID"); adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None; // Set the INSERT command and parameter. adapter.InsertCommand = new SqlCommand( "INSERT INTO Production.ProductCategory (Name) VALUES (@Name);", connection); adapter.InsertCommand.Parameters.Add("@Name", SqlDbType.NVarChar, 50, "Name"); adapter.InsertCommand.UpdatedRowSource = UpdateRowSource.None; // Set the DELETE command and parameter. adapter.DeleteCommand = new SqlCommand( "DELETE FROM Production.ProductCategory " + "WHERE ProductCategoryID=@ProdCatID;", connection); adapter.DeleteCommand.Parameters.Add("@ProdCatID", SqlDbType.Int, 4, "ProductCategoryID"); adapter.DeleteCommand.UpdatedRowSource = UpdateRowSource.None; // Set the batch size. adapter.UpdateBatchSize = batchSize; // Execute the update. adapter.Update(dataTable); } } |
Web.Configで
(<configuration><system.web>内)
<identity impersonate="true" userName="zzzzz" password="xxxxxx"/>
ただし、パスワードが設定してあるユーザーでのみ有効。
※ドメインユーザーの場合はドメイン属性とか domain/zzzzz とかいうユーザ名になるやも。
認証モードがwindowsである必要があると思う。(デフォルトはwindows)
→ <authentication mode="Windows" />
identityに関する一般的な説明
→ http://www.microsoft.com/japan/msdn/net/security/SecNetAP05.aspx
アプリケーションレベルで偽装
→ http://support.microsoft.com/default.aspx?scid=kb;ja;306158
ユーザーDSN→設定したユーザーしかつかえない
システムDSN→他のユーザーも使用可能
たとえばsun.jdbc.odbc.JdbcOdbcDriverを使っていて
javaアプリケーションではつながるが、servletにするとつながらない場合なんかはあやしい。
select * from sysobjectsとかでもだめならより一層怪しい。
you can use FileAttributes.ReparsePoint like this.
Attribute constants name on Win32API
FILE_ATTRIBUTE_REPARSE_POINT
supported OS Win2k or later?
i don’t know, how to create reparse directory
たとえばButtonとValidatorを配置した場合、
Buttonを押すとValidatorが働き、チェックに引っかかった場合はPostBackしない。
(HTMLコントロールのSubmitは除く)
通常はこれでいいが、戻るボタンとかでもValidatorがチェックを開始するのはよろしくない。
この場合はコントロールのCausesValidation プロパティをfalseにセットすればよい。
なお、HTMLコントロールのSubmitなどでもRunat="server"の時は同様の対処が必要。
@PAGE
ディレクティブにて
Trace=\"True\"
とすれば、セッション変数、ポストパラメータなどのメモリ情報を出力することが可能。
AutoPostBack=true
で設定したコントロールの場合
1 |
Page.Request["__EVENTTARGET"] |
から取得する。
コントロールの name
をキーに value
がPOSTされてくる。
複数の Buttonがある場合、押された物しかPOSTされてこないのでそこを利用する。
Buttonのクリックイベントに__doPostBack
を呼び出す javascript function を追加するというかなり強引な手もあるが、
ページ上にButtonしかない(というか PostBackするコントロールが Buttonしかない)場合、__doPostBackは存在しないことがあり、その場合はエラーになるなど、安定しないのでお勧めはしない。
パートナー トランザクション マネージャにより、リモート トランザクションまたはネットワーク トランザクションのサポートが無効にされました。
コンポーネントサービス、
>マイコンピュータ(右クリック)
>プロパティ
「MSDTC」タブ
[セキュリティの構成]ボタン
(シードでの最小構成)
●ネットワークDTCアクセス
●リモートクライアントを許可する
●受信を許可する
●送信を許可する
●認証を必要としない
を、サーバー側、クライアント側双方で設定する。
(サーバー側だけかも)
TIP、XAは有効にしても問題なし。
リモート管理は、用途に応じて。
本当の2003環境であれば認証つけないとまずいと思うが、
ドメインつくってないとだめかも。
http://www.atmarkit.co.jp/fdotnet/dotnettips/183aspsesout/aspsesout.html
state serviceの使い方。
SQLServerモードの解説はない。
Microsoft .NET のすべて
ガベージコレクション入門: Microsoft .NET Framework の自動メモリ管理 Part I
[URL] http://msdn.microsoft.com/ja-jp/library/bb985010.aspx
旧 URL:
http://www.microsoft.com/japan/msdn/net/mag00/GCI.asp
2013/05/31 追記
URLを修正
ListBoxには複数選択モードは存在するが、
DropDownListには存在しない。
たとえばユーザーがDropDownListのアイテムを選択した状態でポストバックが走り、
サーバー処理で違うアイテムを選択状態にしようとすると、
このエラーが発生する。
[csharp]
// wrong case 1
ListItem l = DropDownList1.items.FindByText("item_user_doesn\’t_selected");
l.Selected = true;
[/csharp]
[csharp]
// wrong case 2
items["one more error"].Selected = true
[/csharp]
たとえば上記のような操作の前で、
すべてのSelectedをfalseにするか、
SelectedIndex = -1
とするかで解決する
[csharp]
SelectedIndex = -1;
ListItem l = DropDownList1.items.FindByText("item_user_doesn\’t_selected");
l.Selected = true;
[/csharp]
[csharp]
SelectedIndex = -1;
items["one more error"].Selected = true
[/csharp]
2013/05/31 追記
上記は .NET 1.14のころに書いたもの。
vs2012 では エラーは「DropDownList で複数項目が選択されるように指定できません。」だった。
過去のメモを登録していくつもりがなかなか登録に手間取り古い情報ばかりになってしまっていますのでご利用の際はご注意を
最近のコメント