'Programming/VB.NET'에 해당되는 글 9건
When using Update, the order of execution is as follows:
- The values in the DataRow are moved to the parameter values.
- The OnRowUpdating event is raised.
- The command executes.
- If the command is set to FirstReturnedRecord, then the first returned result is placed in the DataRow.
- If there are output parameters, they are placed in the DataRow.
- The OnRowUpdated event is raised.
- AcceptChanges is called.
Detached | 행을 만들었지만 이 행은 DataRowCollection의 일부가 아닙니다. DataRow는 만들어진 직후 및 컬렉션에 추가되기 전 또는 컬렉션에서 제거된 경우 이 상태가 됩니다. | |
Unchanged | AcceptChanges를 마지막으로 호출한 이후 행이 변경되지 않았습니다. | |
Added | 행이 DataRowCollection에 추가되었으며 AcceptChanges는 호출되지 않았습니다. | |
Deleted | DataRow의 Delete 메서드를 사용하여 행을 삭제했습니다. | |
Modified | 행이 수정되었으며 AcceptChanges는 호출되지 않 |
Private Sub DemonstrateRowState() 'Run a function to create a DataTable with one column. Dim dataTable As DataTable = MakeTable() Dim dataRow As DataRow ' Create a new DataRow. dataRow = dataTable.NewRow() ' Detached row. Console.WriteLine(String.Format("New Row {0}", dataRow.RowState)) dataTable.Rows.Add(dataRow) ' New row. Console.WriteLine(String.Format("AddRow {0}", dataRow.RowState)) dataTable.AcceptChanges() ' Unchanged row. Console.WriteLine(String.Format("AcceptChanges {0}", dataRow.RowState)) dataRow("FirstName") = "Scott" ' Modified row. Console.WriteLine(String.Format("Modified {0}", dataRow.RowState)) dataRow.Delete() ' Deleted row. Console.WriteLine(String.Format("Deleted {0}", dataRow.RowState)) End Sub Private Function MakeTable() As DataTable ' Make a simple table with one column. Dim dt As New DataTable("dataTable") Dim firstName As New DataColumn("FirstName", _ Type.GetType("System.String")) dt.Columns.Add(firstName) Return dt End Function
Original | The row contains its original values. | |
Current | The row contains current values. | |
Proposed | The row contains a proposed value. | |
Default | The default version of DataRowState. For a DataRowState value of Added,Modified or Deleted, the default version is Current. For a DataRowState value ofDetached, the version is Proposed. |
Private Sub DemonstrateRowState() 'Run a function to create a DataTable with one column. Dim dataTable As DataTable = MakeTable() Dim dataRow As DataRow ' Create a new DataRow. dataRow = dataTable.NewRow() ' Detached row. Console.WriteLine(String.Format("New Row {0}", dataRow.RowState)) dataTable.Rows.Add(dataRow) ' New row. Console.WriteLine(String.Format("AddRow {0}", dataRow.RowState)) dataTable.AcceptChanges() ' Unchanged row. Console.WriteLine(String.Format("AcceptChanges {0}", dataRow.RowState)) dataRow("FirstName") = "Scott" ' Modified row. Console.WriteLine(String.Format("Modified {0}", dataRow.RowState)) dataRow.Delete() ' Deleted row. Console.WriteLine(String.Format("Deleted {0}", dataRow.RowState)) End Sub Private Function MakeTable() As DataTable ' Make a simple table with one column. Dim dt As New DataTable("dataTable") Dim firstName As New DataColumn("FirstName", _ Type.GetType("System.String")) dt.Columns.Add(firstName) Return dt End Function
reate table TestTable (id int primary key, fname nvarchar(50), lname nvarchar(50))
insert into TestTable values (1, 'Mike', 'Spike')
insert into TestTable values (2, 'John', 'Johnson')
insert into TestTable values (3, 'Pete', 'Peterson')
--drop table TestTable
Then create a new C# Console application and run the following code:
static void Main(string[] args)
{
string cs = @"Data Source=<your server>;Initial Catalog=<your database>;Integrated Security=SSPI";
string sql = "SELECT id, fname, lname FROM TestTable";
using (SqlConnection con = new SqlConnection(cs))
{
SqlDataAdapter da = new SqlDataAdapter(sql, con);
DataTable dt = new DataTable("Persons");
da.Fill(dt);
Console.WriteLine("Rows are untouched...");
ViewDataTableRowStatus(dt);
// Modify a row.
Console.WriteLine("Modifying the first row...");
dt.Rows[0][1] = "Jake";
ViewDataTableRowStatus(dt);
// Add a row.
Console.WriteLine("Adding a row");
dt.Rows.Add(new object[]{100, "Paul", "Paulson..."});
ViewDataTableRowStatus(dt);
// Now, if calling AcceptChanges() all rows will be set to Unchanged.
Console.WriteLine("Calling AcceptChanges()...");
dt.AcceptChanges();
ViewDataTableRowStatus(dt);
// This means that when we call update on the DataAdapter, it will return 0
// since no rows has actuall been sent to the database. (first we need to build the INSERT and UPDATE commands)
SqlCommandBuilder builder = new SqlCommandBuilder(da);
da.InsertCommand = builder.GetInsertCommand();
da.UpdateCommand = builder.GetUpdateCommand();
int rows = da.Update(dt);
Console.WriteLine("Updated rows: {0}", rows);
}
}
private static void ViewDataTableRowStatus(DataTable dt)
{
foreach (DataRow dr in dt.Rows)
{
Console.WriteLine("Id:{0}\tFirstName: {1}\tRowState: {2}", dr[0].ToString(), dr[1].ToString(), dr.RowState.ToString());
}
Console.WriteLine();
}
이전 버전의 ADO.NET에서는 데이터베이스를 DataSet의 변경 내용으로 업데이트하는 경우 DataAdapter의 Update 메서드에서 데이터베이스에 대해 한 번에 한 행씩 업데이트를 수행했습니다. 또한 지정한DataTable의 행에서 반복될 때 수정되었는지 여부를 확인하기 위해 각 DataRow를 검사했습니다. 행이 수정된 경우에는 해당 행의 RowState 속성 값에 따라 적절한 UpdateCommand, InsertCommand또는 DeleteCommand를 호출했습니다. 그리고 행을 업데이트할 때마다 데이터베이스에 대한 네트워크 라운드트립이 수반되었습니다.
그러나 ADO.NET 2.0에서는 DataAdapter가 UpdateBatchSize 속성을 노출합니다. UpdateBatchSize를 양의 정수 값으로 설정하면 데이터베이스가 업데이트되어 지정된 크기의 배치로 전송됩니다. For example, setting the UpdateBatchSize to 10 will group 10 separate statements and submit them as single batch. UpdateBatchSize를 0으로 설정하면 DataAdapter가 서버에서 처리할 수 있는 최대 배치 크기를 사용합니다. 1로 설정할 경우에는 행이 한 번에 하나씩 전송되므로 배치 업데이트를 사용할 수 없습니다.
너무 큰 배치를 실행하면 성능이 저하될 수 있습니다. 따라서 응용 프로그램을 구현하기 전에 최적의 배치 크기 설정을 테스트해야 합니다.
UpdateBatchSize 속성 사용
When batch updates are enabled, the UpdatedRowSource property value of the DataAdapter's UpdateCommand, InsertCommand, and DeleteCommand should be set to None orOutputParameters. 배치 업데이트를 수행하는 경우 명령의 UpdatedRowSource 속성 값 FirstReturnedRecord 또는 Both는 유효하지 않습니다.
다음 프로시저에서는 UpdateBatchSize 속성을 사용하는 방법을 보여 줍니다. 이 프로시저에서는 Production.ProductCategory 테이블의 ProductCategoryID 및 Name 필드를 표시하는 열이 포함된DataSet 개체와 배치 크기를 나타내는 정수(배치의 행 개수) 등 두 가지 인수를 사용합니다. 이 코드에서는 UpdateCommand, InsertCommand 및 DeleteCommand 속성을 설정하여 새 SqlDataAdapter 개체를 만듭니다. 또한 DataSet 개체에 수정된 행이 있다고 가정합니다. 그리고 UpdateBatchSize 속성을 설정한 다음 업데이트를 실행합니다.
Public Sub BatchUpdate( _ ByVal dataTable As DataTable, ByVal batchSize As Int32) ' Assumes GetConnectionString() returns a valid connection string. Dim connectionString As String = GetConnectionString() ' Connect to the AdventureWorks database. Using connection As New SqlConnection(connectionString) ' Create a SqlDataAdapter. Dim adapter As 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) End Using End Sub
DataAdapter에는 업데이트 관련 이벤트인 RowUpdating 및 RowUpdated가 있습니다. 이전 버전의 ADO.NET에서 일괄 처리가 비활성화되어 있는 경우 각 이벤트는 처리되는 각 행마다 생성됩니다.RowUpdating은 업데이트가 발생하기 전에 생성되며 RowUpdated는 데이터베이스 업데이트가 완료된 뒤에 생성됩니다.
배치 업데이트에 따른 이벤트 동작 변경
일괄 처리가 활성화되면 한 번의 데이터베이스 동작으로 여러 개의 행이 업데이트됩니다. 따라서 RowUpdated 이벤트는 배치마다 한 번씩만 발생하지만 RowUpdating 이벤트는 행이 처리될 때마다 발생합니다. 일괄 처리가 비활성화되면 일대일 인터리빙으로 두 개의 이벤트가 발생합니다. 이 경우 RowUpdating 이벤트 하나와 RowUpdated 이벤트 하나가 한 행에 대해 발생한 후 모든 행이 처리될 때까지RowUpdating 및 RowUpdated 이벤트가 다음 행에 대해 하나씩 발생합니다.
업데이트된 행 액세스
일괄 처리가 비활성화되면 RowUpdatedEventArgs 클래스의 Row 속성을 사용하여 업데이트되는 행에 액세스할 수 있습니다.
일괄 처리가 활성화되면 여러 행에 대해 하나의 RowUpdated 이벤트가 생성됩니다. 따라서 각 행에 대한 Row 속성 값은 null입니다. RowUpdating 이벤트는 계속해서 각 행에 대해 생성됩니다.RowUpdatedEventArgs 클래스의 CopyToRows 메서드를 사용하면 행에 대한 참조를 배열에 복사하여 처리된 행에 액세스할 수 있습니다. 처리 중인 행이 없으면 CopyToRows에서ArgumentNullException이 throw됩니다. CopyToRows 메서드를 호출하기 전에 RowCount 속성을 사용하여 처리된 행 수를 반환합니다.
데이터 오류 처리
리스트박스로부터 아이템 지우기
리스트 박스의 컨트롤명이 lstCustomer이다.
btnRemoveCustomer 버튼이 클릭되면 리스트박스에서 선택된 아이템을 삭제하는 코드
[vb.net] class에 대한 clone의 구현
class는 레퍼런스 타입인데 여기에 ICloneable의 Clone메서드를 구현하여 class의 내부값들을 그대로 복제할 수 있는 기능을 구현한다. 레퍼런스 타입은 하나의 메모리를 가리키고 있으므로 특정 인스턴스 값을 변경하면 다른 인스턴스의 값도 변경된다. 이를 극복하기 위하여 Clone 을 사용한다.
MemberwiseClone 메소드는 모든 value 타입 필드의 값을 그대로 복제하고 참조 타입인 경우는 참조로서 복제한다. 따라서 클래스 내부에 참조 타입 필드는 새로 생성하여 값을 옮겨 넣는 과정이 필요하다(shopping 클래스의 clone메서드와 order클래스의 clone메서드의 차이)
-- order.vb --
Imports System
Imports System.Text
Imports System.Collections.Generic
Public Class Order
Implements ICloneable
Public OrderNumber As String
Public PONumber As String
Public ShippingAddress As String
Public Sub New(ByVal _OrderNumber As String, ByVal _PONumber As String, ByVal _ShippingAddress As String)
OrderNumber = _OrderNumber
PONumber = _PONumber
ShippingAddress = _ShippingAddress
End Sub
' create a clone
Public Function Clone() As Object Implements System.ICloneable.Clone
Return Me.MemberwiseClone
End Function
Public Overrides Function ToString() As String
Return String.Format("Order Number is {0}, and PO number is {1}", OrderNumber, PONumber)
End Function
End Class
-- shopping.vb --
Imports System
Imports System.Text
Imports System.Collections.Generic
Public Class Shopping
Implements ICloneable
Public Orders As New List(Of Order)
Public Sub New()
End Sub
Public Overrides Function ToString() As String
Dim str As New StringBuilder
For Each e As Order In Orders
str.AppendLine(String.Format("order{0}", e.OrderNumber))
Next
Return str.ToString
End Function
Public Function Clone() As Object Implements System.ICloneable.Clone
Dim newShopping As New Shopping
For Each e As Order In Me.Orders
newShopping.Orders.Add(DirectCast(e.Clone, Order))
Next
Return newShopping
End Function
End Class
-- module 1 --
Module Module1
Sub Main()
Dim originalShopping As New Shopping
originalShopping.Orders.Add(New Order("0001", "P001", "address1"))
originalShopping.Orders.Add(New Order("0002", "P002", "address2"))
originalShopping.Orders.Add(New Order("0003", "P003", "address3"))
Dim clonedShopping As Shopping = DirectCast(originalShopping.Clone, Shopping)
originalShopping.Orders(0).OrderNumber = "0005"
originalShopping.Orders(0).PONumber = "P005"
originalShopping.Orders(0).ShippingAddress = "address5"
Console.WriteLine(originalShopping.ToString)
Console.WriteLine(clonedShopping.ToString)
Console.ReadLine()
End Sub
End Module
ISerializable 를 상속 받아 serializable class 구현하기
Imports System
Imports System.IO
Imports System.Text
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Module Module1
Sub Main()
Dim order As New Order("1002", "My First Order", "Seoul, Korea")
Console.WriteLine(order.ToString)
Dim str As Stream = File.Create("MyOrder.bin")
Dim bf As New BinaryFormatter
' serialize the order object specifying another application domatin
' as the destination of the serialized data. All data including the employee addrsss is serialized
bf.Context = New StreamingContext(StreamingContextStates.CrossAppDomain)
bf.Serialize(str, order)
str.Close()
' deselialize and display the order object
str = File.OpenRead("MyOrder.bin")
bf = New BinaryFormatter
order = DirectCast(bf.Deserialize(str), Order)
str.Close()
Console.WriteLine(order.ToString())
' selialize the order object specifying a file as the destination
' of the selialized data. In this case, the order addrsss is not include in the serialized data
str = File.Create("MyNextOrder.bin")
bf = New BinaryFormatter
bf.Context = New StreamingContext(StreamingContextStates.File)
bf.Serialize(str, order)
str.Close()
str = File.OpenRead("MyNextOrder.bin")
bf = New BinaryFormatter
order = DirectCast(bf.Deserialize(str), Order)
str.Close()
Console.WriteLine(order.ToString)
Console.WriteLine("")
Console.WriteLine("Main method is completed, please Enter")
Console.ReadLine()
End Sub
End Module
--- Order.vb ----
Imports System
Imports System.IO
Imports System.Text
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
<Serializable()> _
Public Class Order
Implements ISerializable
Private m_OrderNumber As String
Private m_PONumber As String
Private m_ShippingAddress As String
Public Sub New(ByVal OrderNumber As String, _
ByVal PONumber As String, _
ByVal ShippingAddress As String)
m_OrderNumber = OrderNumber
m_PONumber = PONumber
m_ShippingAddress = ShippingAddress
End Sub
' when deserialized, it will be executed
Private Sub New(ByVal Info As SerializationInfo, ByVal context As StreamingContext)
m_OrderNumber = Info.GetString("OrderNumber")
m_PONumber = Info.GetString("PONumber")
Try
m_ShippingAddress = Info.GetString("ShippingAddress")
Catch ex As Exception
m_ShippingAddress = Nothing
End Try
End Sub
Public Property OrderNumber() As String
Get
Return m_OrderNumber
End Get
Set(ByVal value As String)
m_OrderNumber = value
End Set
End Property
Public Property PONumber() As String
Get
Return m_PONumber
End Get
Set(ByVal value As String)
m_PONumber = value
End Set
End Property
Public Property ShippingAddress() As String
Get
If m_ShippingAddress Is Nothing Then
m_ShippingAddress = String.Empty
End If
Return m_ShippingAddress
End Get
Set(ByVal value As String)
m_ShippingAddress = value
End Set
End Property
''' <summary>
''' when serialized, it will be invoked
''' </summary>
''' <param name="info"></param>
''' <param name="context"></param>
''' <remarks></remarks>
Public Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext) Implements System.Runtime.Serialization.ISerializable.GetObjectData
info.AddValue("OrderNumber", OrderNumber)
info.AddValue("PONumber", PONumber)
If (context.State And StreamingContextStates.File) = 0 Then
info.AddValue("ShippingAddress", ShippingAddress)
End If
End Sub
Public Overrides Function ToString() As String
Dim str As New StringBuilder
str.AppendLine(String.Format("Order Number: {0}", OrderNumber))
str.AppendLine(String.Format("PO Number: {0}", PONumber))
str.AppendLine(String.Format("Shipping Address: {0}", ShippingAddress))
Return str.ToString
End Function
End Class
데이터베이스에서 스토어드 프로시져를 이용하여 테이블을 읽어서 XML파일을 압축하는 코드입니다.
ICSharpCode.SharpZipLib.dll을 참조에 추가한다. 자세한 내용은 http://www.sharpdevelop.net/OpenSource/SharpZipLib/Default.aspx을 참조하도록 합니다.
Imports ICSharpCode.SharpZipLib
' read path
Dim savePath As String = String.Empty
Dim fPath As String = String.Empty
Dim dataVersion As String = String.Empty
Dim CRC32 As Checksums.Crc32 = Nothing
Dim zipOut As Zip.ZipOutputStream = Nothing
Dim zipEntry As Zip.ZipEntry = Nothing
Try
savePath = HttpContext.Current.Server.MapPath(ConfigurationManager.AppSettings("sizer.savePath"))
fPath = System.IO.Path.Combine(savePath, DatafileFileName)
Try
Dim ds As New DataSet("PAXDataSet")
ds.Namespace = "http://tempuri.org/PAXDataSet.xsd"
Dim adapt As New SqlClient.SqlDataAdapter("스토어드 프로시져", ConfigurationManager.ConnectionStrings("PAXConnectionString").ConnectionString)
adapt.Fill(ds)
' 'Table'테이블에서 각 테이블의 이름을 가져와서 이를 맵핑시킨다.
For Each row As DataRow In ds.Tables("Table").Rows
If ds.Tables(row("SourceTable").ToString) IsNot Nothing Then
ds.Tables(row("SourceTable").ToString).TableName = row("MappedTable").ToString
End If
Next
ds.Tables.Remove("Table")
ds.AcceptChanges()
If File.Exists(fPath) Then
File.SetAttributes(fPath, FileAttributes.Normal)
End If
dataVersion = {버전을 넣습니다.}
Dim data As String = ds.GetXml.Trim
Dim buffer() As Byte = System.Text.Encoding.UTF8.GetBytes(data)
zipOut = New SharpZip.Zip.ZipOutputStream(File.Create(fPath))
zipOut.SetLevel(9)
zipOut.SetComment(dataVersion)
zipOut.Password = {패스워드}
CRC32 = New Checksums.Crc32
zipEntry = New Zip.ZipEntry({파일명})
zipEntry.CompressionMethod = ICSharpCode.SharpZipLib.Zip.CompressionMethod.Deflated
zipEntry.Comment = dataVersion
CRC32.Reset()
CRC32.Update(buffer)
zipEntry.Crc = CRC32.Value
zipEntry.DateTime = DateTime.Now
zipEntry.Size = buffer.Length
zipOut.PutNextEntry(zipEntry)
zipOut.Write(buffer, 0, buffer.Length)
zipOut.Flush()
Finally
If zipOut IsNot Nothing Then
Try
zipOut.Finish()
zipOut.Close()
zipOut.Dispose()
Catch : End Try
End If
End Try
Catch ex As Exception
[Throw Exception...]
End Try
''' <summary>
''' Show IP address of my local pc
''' </summary>
''' <remarks></remarks>
Private Sub ShowMyIP()
Dim IPHEntry As IPHostEntry
IPHEntry = System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName())
lblMyIP.Text = IPHEntry.AddressList(0).ToString()
End Sub
Private Function GetMacAddress()
Dim mc As System.Management.ManagementClass
Dim mo As System.Management.ManagementObject
mc = New System.Management.ManagementClass("Win32_NetworkAdapterConfiguration")
Dim moc As System.Management.ManagementObjectCollection = mc.GetInstances()
For Each mo In moc
If mo.Item("IPEnabled") = True Then
Return mo.Item("MacAddress").ToString()
End If
Next
Return String.Empty
End Function