【連結】 ObjectDataSourceを使ったデータ連結で削除コマンドが二回実行される
対象製品
SPREAD for ASP.NET 7.0J
状況
修正済み
詳細
ObjectDataSourceを使ってデータ連結した場合、削除コマンドが二回実行され、削除が正常に実施できません。
【再現手順】
1.新規WebフォームにSPREAD、Button、ObjectDataSourceを配置します
2.Webフォームに下記の再現コードを貼り付けます
3.ObjectDataSource用のビジネスオブジェクトとなるTestAClass.vbファイルを用意します
4.TestAClass.vbに下記のコード(TestAClass.vb)を張り付け、プロジェクトに追加します
5. TestAClass.vb のTestAClassをObjectDataSourceのビジネスオブジェクトとして設定します
6.TestAClassが参照するxml、test.xmlを用意しプロジェクトに追加します
7.test.xmlに下記の内容(test.xml)を張り付けます
8.プロジェクトを起動します
9.SPREAD内にある任意のセルや行を選択し、ボタンを押下します
--- エラーが発生し、行の削除が実行できません
【再現コード】
------------------------------------
WebForm1.aspx.vb
Webフォームクラス
------------------------------------
Public Class WebForm1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Page.IsPostBack Then Return
' FpSpread1の設定
FpSpread1.ActiveSheetView.AutoGenerateColumns = False
FpSpread1.ActiveSheetView.ColumnCount = 3
FpSpread1.ActiveSheetView.Columns(0).DataField = "A1"
FpSpread1.ActiveSheetView.Columns(1).DataField = "A2"
FpSpread1.DataSourceID = "ObjectDataSource1"
FpSpread1.ActiveSheetView.DataKeyField = "ID"
FpSpread1.DataBind()
FpSpread1.ActiveSheetView.AllowDelete = True
' Buttonの設定
Button1.OnClientClick = "TestA();return false;"
Button1.UseSubmitBehavior = False
End Sub
End Class
------------------------------------
WebForm1.aspx
クライアント側スクリプト
------------------------------------
<script type="text/javascript">
function TestA() {
var spreadA = document.getElementById("FpSpread1");
spreadA.Delete();
}
</script>
------------------------------------
TestAClass.vb
------------------------------------
Imports Microsoft.VisualBasic
Imports System
Imports System.Web
Imports System.Data
Imports System.ComponentModel
Public Class TestAClass
Private ds As DataSet = New System.Data.DataSet()
Private filePath As String = HttpContext.Current.Server.MapPath("~/App_Data/test.xml")
Public Sub New()
ds.ReadXml(filePath, Data.XmlReadMode.ReadSchema)
End Sub
Public Function GetTest() As DataSet
Return ds
End Function
Public Sub DeleteTest(ByVal ID As Integer)
Dim row As DataRow = ds.Tables(0).Rows.Find(ID)
ds.Tables(0).Rows.Remove(row)
ds.WriteXml(filePath, Data.XmlWriteMode.WriteSchema)
End Sub
End Class
------------------------------------
test.xml
------------------------------------
<?xml version="1.0" standalone="yes"?>
<dsTest>
<xs:schema id="dsTest" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="dsTest" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="TestA">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:int" />
<xs:element name="A1" type="xs:int" minOccurs="0" />
<xs:element name="A2" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//TestA" />
<xs:field xpath="ID" />
</xs:unique>
</xs:element>
</xs:schema>
<TestA>
<ID>0</ID>
<A1>0</A1>
<A2>dataA0</A2>
</TestA>
<TestA>
<ID>1</ID>
<A1>1</A1>
<A2>dataA1</A2>
</TestA>
<TestA>
<ID>2</ID>
<A1>2</A1>
<A2>dataA2</A2>
</TestA>
<TestA>
<ID>3</ID>
<A1>3</A1>
<A2>dataA3</A2>
</TestA>
<TestA>
<ID>4</ID>
<A1>4</A1>
<A2>dataA4</A2>
</TestA>
<TestA>
<ID>5</ID>
<A1>5</A1>
<A2>dataA5</A2>
</TestA>
<TestA>
<ID>6</ID>
<A1>6</A1>
<A2>dataA6</A2>
</TestA>
<TestA>
<ID>7</ID>
<A1>7</A1>
<A2>dataA7</A2>
</TestA>
<TestA>
<ID>8</ID>
<A1>8</A1>
<A2>dataA8</A2>
</TestA>
<TestA>
<ID>9</ID>
<A1>9</A1>
<A2>dataA9</A2>
</TestA>
</dsTest>
【再現手順】
1.新規WebフォームにSPREAD、Button、ObjectDataSourceを配置します
2.Webフォームに下記の再現コードを貼り付けます
3.ObjectDataSource用のビジネスオブジェクトとなるTestAClass.vbファイルを用意します
4.TestAClass.vbに下記のコード(TestAClass.vb)を張り付け、プロジェクトに追加します
5. TestAClass.vb のTestAClassをObjectDataSourceのビジネスオブジェクトとして設定します
6.TestAClassが参照するxml、test.xmlを用意しプロジェクトに追加します
7.test.xmlに下記の内容(test.xml)を張り付けます
8.プロジェクトを起動します
9.SPREAD内にある任意のセルや行を選択し、ボタンを押下します
--- エラーが発生し、行の削除が実行できません
【再現コード】
------------------------------------
WebForm1.aspx.vb
Webフォームクラス
------------------------------------
Public Class WebForm1
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Page.IsPostBack Then Return
' FpSpread1の設定
FpSpread1.ActiveSheetView.AutoGenerateColumns = False
FpSpread1.ActiveSheetView.ColumnCount = 3
FpSpread1.ActiveSheetView.Columns(0).DataField = "A1"
FpSpread1.ActiveSheetView.Columns(1).DataField = "A2"
FpSpread1.DataSourceID = "ObjectDataSource1"
FpSpread1.ActiveSheetView.DataKeyField = "ID"
FpSpread1.DataBind()
FpSpread1.ActiveSheetView.AllowDelete = True
' Buttonの設定
Button1.OnClientClick = "TestA();return false;"
Button1.UseSubmitBehavior = False
End Sub
End Class
------------------------------------
WebForm1.aspx
クライアント側スクリプト
------------------------------------
<script type="text/javascript">
function TestA() {
var spreadA = document.getElementById("FpSpread1");
spreadA.Delete();
}
</script>
------------------------------------
TestAClass.vb
------------------------------------
Imports Microsoft.VisualBasic
Imports System
Imports System.Web
Imports System.Data
Imports System.ComponentModel
Public Class TestAClass
Private ds As DataSet = New System.Data.DataSet()
Private filePath As String = HttpContext.Current.Server.MapPath("~/App_Data/test.xml")
Public Sub New()
ds.ReadXml(filePath, Data.XmlReadMode.ReadSchema)
End Sub
Public Function GetTest() As DataSet
Return ds
End Function
Public Sub DeleteTest(ByVal ID As Integer)
Dim row As DataRow = ds.Tables(0).Rows.Find(ID)
ds.Tables(0).Rows.Remove(row)
ds.WriteXml(filePath, Data.XmlWriteMode.WriteSchema)
End Sub
End Class
------------------------------------
test.xml
------------------------------------
<?xml version="1.0" standalone="yes"?>
<dsTest>
<xs:schema id="dsTest" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="dsTest" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="TestA">
<xs:complexType>
<xs:sequence>
<xs:element name="ID" type="xs:int" />
<xs:element name="A1" type="xs:int" minOccurs="0" />
<xs:element name="A2" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//TestA" />
<xs:field xpath="ID" />
</xs:unique>
</xs:element>
</xs:schema>
<TestA>
<ID>0</ID>
<A1>0</A1>
<A2>dataA0</A2>
</TestA>
<TestA>
<ID>1</ID>
<A1>1</A1>
<A2>dataA1</A2>
</TestA>
<TestA>
<ID>2</ID>
<A1>2</A1>
<A2>dataA2</A2>
</TestA>
<TestA>
<ID>3</ID>
<A1>3</A1>
<A2>dataA3</A2>
</TestA>
<TestA>
<ID>4</ID>
<A1>4</A1>
<A2>dataA4</A2>
</TestA>
<TestA>
<ID>5</ID>
<A1>5</A1>
<A2>dataA5</A2>
</TestA>
<TestA>
<ID>6</ID>
<A1>6</A1>
<A2>dataA6</A2>
</TestA>
<TestA>
<ID>7</ID>
<A1>7</A1>
<A2>dataA7</A2>
</TestA>
<TestA>
<ID>8</ID>
<A1>8</A1>
<A2>dataA8</A2>
</TestA>
<TestA>
<ID>9</ID>
<A1>9</A1>
<A2>dataA9</A2>
</TestA>
</dsTest>
回避方法
Service Pack 3(v7.0.4017.2010)で修正済み。
Service Pack 3(v7.0.4017.2010)より前のバージョンでは次の回避方法が有効です。
------------------------------------------
事前に行が存在するかどうかのチェック処理を実装することで本現象の回避が可能です。
【再現コードへの回避策適用例】
Public Sub DeleteTest(ByVal ID As Integer)
Dim row As DataRow = ds.Tables(0).Rows.Find(ID)
If (Not row Is Nothing) Then
ds.Tables(0).Rows.Remove(row)
ds.WriteXml(filePath, Data.XmlWriteMode.WriteSchema)
End If
End Sub
Service Pack 3(v7.0.4017.2010)より前のバージョンでは次の回避方法が有効です。
------------------------------------------
事前に行が存在するかどうかのチェック処理を実装することで本現象の回避が可能です。
【再現コードへの回避策適用例】
Public Sub DeleteTest(ByVal ID As Integer)
Dim row As DataRow = ds.Tables(0).Rows.Find(ID)
If (Not row Is Nothing) Then
ds.Tables(0).Rows.Remove(row)
ds.WriteXml(filePath, Data.XmlWriteMode.WriteSchema)
End If
End Sub