데이터 소스 제어Data Source Controls

로 마이크로 소프트by Microsoft

ASP.NET 1.x의 DataGrid 제어는 웹 응용 프로그램의 데이터 액세스가 크게 개선되었습니다.The DataGrid control in ASP.NET 1.x marked a great improvement in data access in Web applications. 그러나, 그것은 사용자 친화적인 되지 않았습니다.However, it wasn't as user-friendly as it could have been. 여전히 많은 유용한 기능을 얻기 위해 상당한 양의 코드가 필요했습니다.It still required a considerable amount of code to obtain much useful functionality from it. 이러한 1.x의 모든 데이터 액세스 노력의 모델입니다.Such is the model in all data access endeavors in 1.x.

ASP.NET 1.x의 DataGrid 제어는 웹 응용 프로그램의 데이터 액세스가 크게 개선되었습니다.The DataGrid control in ASP.NET 1.x marked a great improvement in data access in Web applications. 그러나, 그것은 사용자 친화적인 되지 않았습니다.However, it wasn't as user-friendly as it could have been. 여전히 많은 유용한 기능을 얻기 위해 상당한 양의 코드가 필요했습니다.It still required a considerable amount of code to obtain much useful functionality from it. 이러한 1.x의 모든 데이터 액세스 노력의 모델입니다.Such is the model in all data access endeavors in 1.x.

ASP.NET 2.0은 데이터 원본 컨트롤을 사용하여 부분적으로 이 주소를 처리합니다.ASP.NET 2.0 addresses this with in part with data source controls. ASP.NET 2.0의 데이터 원본 컨트롤은 개발자에게 데이터 검색, 데이터 표시 및 데이터 편집을 위한 선언적 모델을 제공합니다.The data source controls in ASP.NET 2.0 provide developers with a declarative model for retrieving data, displaying data, and editing data. 데이터 원본 컨트롤의 목적은 해당 데이터의 원본에 관계없이 데이터 바인딩된 컨트롤에 데이터를 일관되게 표현하는 것입니다.The purpose of data source controls is to provide a consistent representation of data to data-bound controls regardless of the source of those data. ASP.NET 2.0의 데이터 원본 컨트롤의 핵심은 DataSourceControl 추상 클래스입니다.At the heart of the data source controls in ASP.NET 2.0 is the DataSourceControl abstract class. DataSourceControl 클래스는 IDataSource 인터페이스와 IListSource 인터페이스의 기본 구현을 제공하며, 후자는 데이터 원본 컨트롤을 데이터 바인딩 된 컨트롤의 DataSource로 할당하고 (나중에 설명한 새 DataSourceId 속성을 통해) 목록으로 데이터를 노출할 수 있습니다.The DataSourceControl class provides a base implementation of the IDataSource interface and the IListSource interface, the latter of which allows you to assign the data source control as the DataSource of a data-bound control (via the new DataSourceId property discussed later) and expose the data therein as a list. 데이터 원본 컨트롤의 각 데이터 목록은 DataSourceView 개체로 노출됩니다.Each list of data from a data source control is exposed as a DataSourceView object. DataSourceView 인스턴스에 대한 액세스는 IDataSource 인터페이스에서 제공됩니다.Access to the DataSourceView instances is provided by the IDataSource interface. 예를 들어 GetViewNames 메서드는 특정 데이터 원본 컨트롤과 연결된 DataSourceView를 등록할 수 있는 ICollection을 반환하고 GetView 메서드를 사용하면 이름으로 특정 DataSourceView 인스턴스에 액세스할 수 있습니다.For example, the GetViewNames method returns an ICollection that allows you to enumerate the DataSourceViews associated with a particular data source control, and the GetView method allows you to access a particular DataSourceView instance by name.

데이터 원본 컨트롤에는 사용자 인터페이스가 없습니다.Data source controls have no user-interface. 선언적 구문을 지원하고 원하는 경우 페이지 상태에 액세스할 수 있도록 서버 컨트롤로 구현됩니다.They are implemented as server controls so that they can support declarative syntax and so that they have access to page state if desired. 데이터 원본 컨트롤은 클라이언트에 HTML 태그를 렌더링하지 않습니다.Data source controls do not render any HTML markup to the client.

Note

나중에 살펴보겠습니다.As you'll see later, there are also caching benefits obtained by using data source controls.

연결 문자열 저장Storing Connection Strings

데이터 원본 컨트롤을 구성하는 방법을 살펴보기 전에 연결 문자열과 관련하여 ASP.NET 2.0의 새로운 기능을 다루어야 합니다.Before we get into looking at how to configure data source controls, we should cover a new capability in ASP.NET 2.0 concerning connection strings. ASP.NET 2.0은 런타임에 동적으로 읽을 수 있는 연결 문자열을 쉽게 저장할 수 있는 구성 파일에 새 섹션을 소개합니다.ASP.NET 2.0 introduces a new section in the configuration file that allows you to easily store connection strings that can be read dynamically at runtime. <연결Strings> 섹션을 사용하면 연결 문자열을 쉽게 저장할 수 있습니다.The <connectionStrings> section makes it easy to store connection strings.

아래 코드 조각은 새 연결 문자열을 추가합니다.The snippet below adds a new connection string.

<connectionStrings> <add name="Northwind" connectionString="Data Source=localhost; Integrated Security=SSPI;Initial Catalog=Northwind;" providerName="System.Data.SqlClient" /> </connectionStrings>

Note

<appSettings> <섹션과 마찬가지로 연결문자열> 섹션은 구성 파일의 <system.web> 섹션 외부에 나타납니다.Just as with the <appSettings> section, the <connectionStrings> section appears outside of the <system.web> section in the configuration file.

이 연결 문자열을 사용 하려면 서버 컨트롤의 ConnectionString 특성을 설정할 때 다음 구문을 사용할 수 있습니다.To use this connection string, you can use the following syntax when setting the ConnectionString attribute of a server control.

ConnectionString="<%$ ConnectionStrings:Northwind%>"

<연결Strings> 섹션은 중요한 정보가 노출되지 않도록 암호화할 수도 있습니다.The <connectionStrings> section can also be encrypted so that sensitive information is not exposed. 이 기능은 이후 단원에서 다룹니다.That ability will be covered in a later module.

데이터 원본 캐싱Caching Data Sources

각 DataSourceControl은 캐싱을 구성하기 위한 네 가지 속성을 제공합니다. 인에이블캐칭, 캐시지속, 캐시익스피어레이션정책 및 캐시키독립성.Each DataSourceControl provides four properties for configuring caching; EnableCaching, CacheDuration, CacheExpirationPolicy, and CacheKeyDependency.

인에이블캐칭EnableCaching

EnableCaching은 데이터 원본 컨트롤에 대해 캐싱이 활성화되었는지 여부를 결정하는 부울 속성입니다.EnableCaching is a Boolean property that determines whether or not caching is enabled for the data source control.

캐시지속 속성CacheDuration Property

CacheDuration 속성은 캐시가 유효한 상태로 유지되는 시간(초)을 설정합니다.The CacheDuration property sets the number of seconds that the cache remains valid. 이 속성을 0으로 설정하면 캐시가 명시적으로 무효화될 때까지 유효하게 유지됩니다.Setting this property to 0 causes the cache to remain valid until explicitly invalidated.

캐시익기정책 속성CacheExpirationPolicy Property

CacheExpirationPolicy 속성은 절대 또는 슬라이딩으로 설정할 수 있습니다.The CacheExpirationPolicy property can be set to either Absolute or Sliding. 절대로 설정하면 데이터가 캐시될 최대 시간이 CacheDuration 속성에서 지정한 초(초)임을 의미합니다.Setting it to Absolute means that the maximum amount of time that the data will be cached is the number of seconds specified by the CacheDuration property. 슬라이딩으로 설정하면 각 작업이 수행될 때 만료 시간이 재설정됩니다.By setting it to Sliding, the expiration time is reset when each operation is performed.

캐시키리퍼렌디속성CacheKeyDependency Property

CacheKeyDependncy 속성에 대해 문자열 값을 지정하면 ASP.NET 해당 문자열을 기반으로 새 캐시 종속성을 설정합니다.If a string value is specified for the CacheKeyDependency property, ASP.NET will set up a new cache dependency based on that string. 이렇게 하면 CacheKeyDependency를 변경하거나 제거하기만 하면 캐시를 명시적으로 무효화할 수 있습니다.This allows you to explicitly invalidate the cache by simply changing or removing the CacheKeyDependency.

중요: 가장이 활성화되어 있고 데이터 원본 및/또는 데이터 콘텐츠에 대한 액세스가 클라이언트 ID를 기반으로 하는 경우 EnableCaching을 False로 설정하여 캐싱을 사용하지 않도록 설정하는 것이 좋습니다.Important: If impersonation is enabled and access to the data source and/or content of data are based upon client identity, it is recommended that caching be disabled by setting EnableCaching to False. 이 시나리오에서 캐싱을 사용하도록 설정하고 원래 데이터를 요청한 사용자 이외의 사용자가 요청을 발행하는 경우 데이터 원본에 대한 권한 부여가 적용되지 않습니다.If caching is enabled in this scenario and a user other than the user who originally requested the data issues a request, authorization to the data source is not enforced. 데이터는 단순히 캐시에서 제공됩니다.The data will simply be served from cache.

SqlDataSource 컨트롤The SqlDataSource Control

SqlDataSource 컨트롤을 사용하면 개발자가 ADO.NET 지원하는 모든 관계형 데이터베이스에 저장된 데이터에 액세스할 수 있습니다.The SqlDataSource control allows a developer to access data stored in any relational database that supports ADO.NET. System.Data.SqlClient 공급자를 사용하여 SQL Server 데이터베이스, System.Data.OleDb 공급자, System.Data.Odbc 공급자 또는 System.Data.OracleClient 공급자에 액세스하여 오라클에 액세스할 수 있습니다.It can use the System.Data.SqlClient provider to access a SQL Server database, the System.Data.OleDb provider, the System.Data.Odbc provider, or the System.Data.OracleClient provider to access Oracle. 따라서 SqlDataSource는 SQL Server 데이터베이스의 데이터에 액세스하는 데만 사용되는 것이 아닙니다.Therefore, the SqlDataSource is certainly not only used for accessing data in a SQL Server database.

SqlDataSource를 사용 하려면 연결 String 속성에 대 한 값을 제공 하 고 SQL 명령 또는 저장 프로시저를 지정 합니다.In order to use the SqlDataSource, you simply provide a value for the ConnectionString property and specify a SQL command or stored procedure. SqlDataSource 컨트롤은 기본 ADO.NET 아키텍처 작업을 처리합니다.The SqlDataSource control takes care of working with the underlying ADO.NET architecture. 연결을 열고, 데이터 원본을 쿼리하거나, 저장된 프로시저를 실행하고, 데이터를 반환한 다음, 연결을 닫습니다.It opens the connection, queries the data source or executes the stored procedure, returns the data, and then closes the connection for you.

Note

DataSourceControl 클래스는 자동으로 연결을 닫기 때문에 데이터베이스 연결 누수로 인해 생성된 고객 호출 수를 줄여야 합니다.Because the DataSourceControl class automatically closes the connection for you, it should reduce the number of customer calls generated by leaking database connections.

아래 코드 코드 조각은 위와 같이 구성 파일에 저장된 연결 문자열을 사용하여 DropDownList 컨트롤을 SqlDataSource 컨트롤에 바인딩합니다.The code snippet below binds a DropDownList control to a SqlDataSource control using the connection string that is stored in the configuration file as shown above.

<asp:SqlDataSource id="SqlDataSource1" runat="server" DataSourceMode="DataReader" ConnectionString="<%$ ConnectionStrings:Northwind%>" SelectCommand="SELECT EmployeeID, LastName FROM Employees"> </asp:SqlDataSource><asp:DropDownList id="ListBox1" runat="server" DataTextField="LastName" DataValueField="EmployeeID" DataSourceID="SqlDataSource1"> </asp:DropDownList>

위에서 설명한 대로 SqlDataSource의 DataSourceMode 속성은 데이터 원본에 대한 모드를 지정합니다.As illustrated above, the DataSourceMode property of the SqlDataSource specifies the mode for the data source. 위의 예에서 DataSourceMode는 DataReader로 설정됩니다.In the example above, the DataSourceMode is set to DataReader. 이 경우 SqlDataSource는 정방향 전용 및 읽기 전용 커서를 사용하여 IDataReader 개체를 반환합니다.In that case, the SqlDataSource will return an IDataReader object using a forward-only and read-only cursor. 반환되는 지정된 유형의 개체는 사용되는 공급자에 의해 제어됩니다.The specified type of object that is returned is controlled by the provider that is used. 이 경우 web.config 파일의 <연결Strings 섹션에 지정된 대로> System.Data.SqlClient 공급자를 사용하고 있습니다.In this case, I'm using the System.Data.SqlClient provider as specified in the <connectionStrings> section of the web.config file. 따라서 반환되는 개체는 SqlDataReader 형식입니다.Therefore, the object that is returned will be of type SqlDataReader. DataSet의 DataSourceMode 값을 지정하면 서버의 DataSet에 데이터를 저장할 수 있습니다.By specifying a DataSourceMode value of DataSet, the data can be stored in a DataSet on the server. 이 모드를 사용하면 정렬, 페이징 등과 같은 기능을 추가할 수 있습니다. SqlDataSource를 GridView 컨트롤에 데이터 바인딩했다면 데이터 집합 모드를 선택했을 것입니다.This mode allows you to add features such as sorting, paging, etc. If I had been data-binding the SqlDataSource to a GridView control, I would have chosen the DataSet mode. 그러나 드롭다운리스트의 경우 데이터 리더 모드가 올바른 선택입니다.However, in the case of a DropDownList, the DataReader mode is the correct choice.

Note

SqlDataSource 또는 AccessDataSource를 캐싱할 때 DataSourceMode 속성을 데이터 집합으로 설정해야 합니다.When caching a SqlDataSource or an AccessDataSource, the DataSourceMode property must be set to DataSet. DataSourceMode의 DataSourceMode를 사용하여 캐싱을 사용하도록 설정하면 예외가 발생합니다.An exception will occur if you enable caching with a DataSourceMode of DataReader.

SqlDataSource 속성SqlDataSource Properties

다음은 SqlDataSource 컨트롤의 속성 중 일부입니다.The following are some of the properties of the SqlDataSource control.

취소선택온Null매개변수CancelSelectOnNullParameter

매개 변수 중 하나가 null인 경우 선택 명령이 취소되는지 여부를 지정하는 부울 값입니다.A Boolean value that specifies whether a select command is canceled if one of the parameters is null. 기본적으로 true입니다.True by default.

충돌 감지ConflictDetection

여러 사용자가 동시에 데이터 원본을 업데이트할 수 있는 경우 ConflictDetection 속성은 SqlDataSource 컨트롤의 동작을 결정합니다.In a situation where multiple users may be updating a data source at the same time, the ConflictDetection property determines the behavior of the SqlDataSource control. 이 속성은 충돌옵션 열거형의 값 중 하나를 평가합니다.This property evaluates to one of the values of the ConflictOptions enumeration. 이러한 값은 비교AllValues덮어쓰기변경.Those values are CompareAllValues and OverwriteChanges. Overwrite변경으로 설정된 경우 데이터 원본에 데이터를 작성하는 마지막 사람이 이전 변경 내용을 덮어씁니다.If set to OverwriteChanges, the last person to write data to the data source overwrites any previous changes. 그러나 충돌 감지 속성이 CompareAllValues로 설정된 경우 SelectCommand에서 반환하는 열에 대해 매개 변수가 만들어지고, SelectCommand가 실행된 이후 값이 변경되었는지 여부를 확인할 수 있도록 해당 각 열의 원래 값을 보유하도록 매개 변수도 만들어집니다.However, if the ConflictDetection property is set to CompareAllValues, parameters get created for the columns returned by the SelectCommand and parameters are also created to hold the original values in each of those columns allowing the SqlDataSource to determine whether or not the values have changed since the SelectCommand was executed.

명령 삭제DeleteCommand

데이터베이스에서 행을 삭제할 때 사용되는 SQL 문자열을 설정하거나 가져옵니다.Sets or gets the SQL string used when deleting rows from the database. SQL 쿼리 또는 저장 프로시저 이름일 수 있습니다.This can either be a SQL query or a stored procedure name.

삭제명령 유형DeleteCommandType

SQL 쿼리(Text) 또는 저장 프로시저(저장 프로시저)를 삭제 명령 의 형식을 설정하거나 가져옵니다.Sets or gets the type of delete command, either a SQL query (Text) or a stored procedure (StoredProcedure).

삭제매개 변수DeleteParameters

SqlDataSource 컨트롤과 연결된 SqlDataSourceView 개체의 DeleteCommand에서 사용되는 매개 변수를 반환합니다.Returns the parameters that are used by the DeleteCommand of the SqlDataSourceView object associated with the SqlDataSource control.

이전 값매개 변수 형식 문자열OldValuesParameterFormatString

이 속성은 ConflictDetection 속성이 CompareAllValues로 설정된 경우 원래 값 매개 변수의 형식을 지정하는 데 사용됩니다.This property is used to specify the format of the original value parameters in cases where the ConflictDetection property is set to CompareAllValues. 기본값은 {0} 원래 값 매개 변수가 원래 매개 변수와 동일한 이름을 사용한다는 것을 의미합니다.The default is {0} which means that original value parameters will take the same name as the original parameter. 즉, 필드 이름이 EmployeeID인 경우 원래 값 매개 @EmployeeID변수는 입니다.In other words, if the field name is EmployeeID, the original value parameter would be @EmployeeID.

SelectCommandSelectCommand

데이터베이스에서 데이터를 검색하는 데 사용되는 SQL 문자열을 설정하거나 가져옵니다.Sets or gets the SQL string that is used to retrieve data from the database. SQL 쿼리 또는 저장 프로시저 이름일 수 있습니다.This can either be a SQL query or a stored procedure name.

명령 유형 선택SelectCommandType

SQL 쿼리(Text) 또는 저장 프로시저(저장 프로시저)를 선택 명령의 형식을 설정하거나 가져옵니다.Sets or gets the type of select command, either a SQL query (Text) or a stored procedure (StoredProcedure).

선택매개 변수SelectParameters

SqlDataSource 컨트롤과 연결된 SqlDataSourceView 개체의 SelectCommand에서 사용하는 매개 변수를 반환합니다.Returns the parameters that are used by the SelectCommand of the SqlDataSourceView object associated with the SqlDataSource control.

정렬 매개 변수 이름SortParameterName

데이터 원본 컨트롤에서 검색한 데이터를 정렬할 때 사용되는 저장 프로시저 매개 변수의 이름을 가져옵니다.Gets or sets the name of a stored procedure parameter that is used when sorting data retrieved by the data source control. SelectCommandType이 저장프로시프로로 설정된 경우에만 유효합니다.Valid only when SelectCommandType is set to StoredProcedure.

SqlCache 종속성SqlCacheDependency

SQL Server 캐시 종속성에 사용되는 데이터베이스와 테이블을 지정하는 세미 콜론 구분 문자열입니다.A semi-colon delimited string specifying the databases and tables used in a SQL Server cache dependency. (SQL 캐시 종속성은 이후 모듈에서 설명합니다.)(SQL cache dependencies will be discussed in a later module.)

업데이트 명령UpdateCommand

데이터베이스의 데이터를 업데이트할 때 사용되는 SQL 문자열을 설정하거나 가져옵니다.Sets or gets the SQL string that is used when updating data in the database. SQL 쿼리 또는 저장 프로시저 이름일 수 있습니다.This can either be a SQL query or a stored procedure name.

업데이트 명령 유형UpdateCommandType

SQL 쿼리(Text) 또는 저장 프로시저(저장 프로시저)를 설정하거나 업데이트 명령 의 형식을 가져옵니다.Sets or gets the type of update command, either a SQL query (Text) or a stored procedure (StoredProcedure).

업데이트매개 변수UpdateParameters

SqlDataSource 컨트롤과 연결된 SqlDataSourceView 개체의 UpdateCommand에서 사용하는 매개 변수를 반환합니다.Returns the parameters that are used by the UpdateCommand of the SqlDataSourceView object associated with the SqlDataSource control.

액세스 데이터 소스 제어The AccessDataSource Control

AccessDataSource 컨트롤은 SqlDataSource 클래스에서 파생되며 Microsoft Access 데이터베이스에 데이터 바인딩에 사용됩니다.The AccessDataSource control derives from the SqlDataSource class and is used to data-bind to a Microsoft Access database. AccessDataSource 컨트롤에 대한 연결 String 속성은 읽기 전용 속성입니다.The ConnectionString property for the AccessDataSource control is a read-only property. AccessString 속성을 사용하는 대신 DataFile 속성은 아래와 같이 액세스 데이터베이스를 가리키는 데 사용됩니다.Instead of using the ConnectionString property, the DataFile property is used to point to the Access Database as shown below.

<asp:AccessDataSource id="AccessDataSource1" runat="server" DataFile="~/App_Data/Northwind.mdb"> </asp:AccessDataSource>

AccessDataSource는 항상 기본 SqlDataSource의 공급자 이름을 System.Data.OleDb로 설정하고 Microsoft.Jet.OLEDB.4.0 OLE DB 공급자를 사용하여 데이터베이스에 연결합니다.The AccessDataSource will always set the ProviderName of the base SqlDataSource to System.Data.OleDb and connects to the database using the Microsoft.Jet.OLEDB.4.0 OLE DB provider. AccessDataSource 컨트롤을 사용하여 암호로 보호된 액세스 데이터베이스에 연결할 수 없습니다.You cannot use the AccessDataSource control to connect to a password-protected Access database. 암호로 보호된 데이터베이스에 연결해야 하는 경우 SqlDataSource 컨트롤을 사용해야 합니다.If you have to connect to a password protected database, you should use the SqlDataSource control.

Note

웹 사이트에 저장된 액세스 데이터베이스는 앱_데이터 디렉터리에 배치해야 합니다.Access databases stored within the Web site should be placed in the App_Data directory. ASP.NET 이 디렉터리에서 파일을 찾아볼 수 없습니다.ASP.NET does not allow files in this directory to be browsed. Access 데이터베이스를 사용할 때 프로세스 계정 읽기 및_쓰기 권한을 앱 데이터 디렉터리에 부여해야 합니다.You will need to grant the process account Read and Write permissions to the App_Data directory when using Access databases.

XmlData소스 제어The XmlDataSource Control

XmlDataSource는 XML 데이터를 데이터 바인딩 컨트롤에 데이터 바인딩하는 데 사용됩니다.The XmlDataSource is used to data-bind XML data to data-bound controls. DataFile 속성을 사용하여 XML 파일에 바인딩하거나 Data 속성을 사용하여 XML 문자열에 바인딩할 수 있습니다.You can bind to an XML file using the DataFile property or you can bind to an XML string using the Data property. XmlDataSource는 XML 특성을 바인딩 가능한 필드로 노출합니다.The XmlDataSource exposes XML attributes as bindable fields. 특성으로 표시되지 않는 값에 바인딩해야 하는 경우 XSL 변환을 사용해야 합니다.In cases where you need to bind to values that are not represented as attributes, you will need to use an XSL transform. XPath 식을 사용하여 XML 데이터를 필터링할 수도 있습니다.You can also use XPath expressions to filter XML data.

다음 XML 파일을 고려하십시오.Consider the following XML file:

<?xml version="1.0" encoding="utf-8" ?> <People> <Person FirstName="Jake" LastName="Stone"> <Address> <Street>345 Maple St.</Street> <City>Redmond</City> <Region>WA</Region> <ZipCode>01434</ZipCode> </Address> <Job> <Title>CEO</Title> <Description>Develops company strategies.</Description> </Job> </Person> <Person FirstName="Jacob" LastName="Ladder"> <Address> <Street>123 Elm St.</Street> <City>Seattle</City> <Region>WA</Region> <ZipCode>11223</ZipCode> </Address> <Job> <Title>Attorney</Title> <Description>Reviews legal issues.</Description> </Job> </Person> <Person FirstName="Angela" LastName="Hound"> <Address> <Street>34 Palm Avenue</Street> <City>Renton</City> <Region>WA</Region> <ZipCode>63910</ZipCode> </Address> <Job> <Title>IT Director</Title> <Description>In charge of corporate network.</Description> </Job> </Person> </People>

XmlDataSource는 <> 사람/사람의 XPath 속성을 사용하여 사람 노드만 필터링합니다.Notice that the XmlDataSource uses an XPath property of People/Person in order to filter on just the <Person> nodes. 그런 다음 드롭다운리스트는 DataTextField 속성을 사용하여 LastName 특성에 데이터 바인딩합니다.The DropDownList then data-binds to the LastName attribute using the DataTextField property.

XmlDataSource 컨트롤은 주로 읽기 전용 XML 데이터에 데이터 바인딩에 사용되지만 XML 데이터 파일을 편집할 수 있습니다.While the XmlDataSource control is primarily used to data-bind to read-only XML data, it is possible to edit the XML data file. 이러한 경우 XML 파일의 정보 자동 삽입, 업데이트 및 삭제는 다른 데이터 원본 컨트롤과 마찬가지로 자동으로 수행되지 않습니다.Note that in such cases, automatic insertion, updating, and deletion of information in the XML file does not happen automatically as it does with other data source controls. 대신 XmlDataSource 컨트롤의 다음 방법을 사용하여 데이터를 수동으로 편집하는 코드를 작성해야 합니다.Instead, you will have to write code to manually edit the data using the following methods of the XmlDataSource control.

겟Xml문서GetXmlDocument

XmlDataSource에서 검색한 XML 코드가 포함된 XmlDocument 개체를 검색합니다.Retrieves an XmlDocument object containing the XML code retrieved by the XmlDataSource.

저장Save

인메모리 XmlDocument를 데이터 원본에 다시 저장합니다.Saves the in-memory XmlDocument back to the data source.

Save 메서드는 다음 두 조건이 충족될 때만 작동한다는 것을 깨닫는 것이 중요합니다.It's important to realize that the Save method will only work when the following two conditions are met:

  1. XmlDataSource는 DataFile 속성을 사용하여 데이터 속성 대신 XML 파일에 바인딩하여 메모리 내 XML 데이터에 바인딩합니다.The XmlDataSource is using the DataFile property to bind to an XML file instead of the Data property to bind to in-memory XML data.
  2. 변환 또는 TransformFile 속성을 통해 변환이 지정되지 않습니다.No transformation is specified via the Transform or TransformFile property.

또한 Save 메서드는 여러 사용자가 동시에 호출할 때 예기치 않은 결과를 얻을 수 있습니다.Note also that the Save method can yield unexpected results when called by multiple users concurrently.

개체 데이터 소스 컨트롤The ObjectDataSource Control

지금까지 적용한 데이터 원본 컨트롤은 데이터 원본 컨트롤이 데이터 저장소에 직접 통신하는 2계층 응용 프로그램에 적합합니다.The data source controls that we have covered up to this point are excellent choices for two-tier applications where the data source control communicates directly to the data store. 그러나 많은 실제 응용 프로그램은 데이터 원본 컨트롤이 비즈니스 개체와 통신해야 하는 다중 계층 응용 프로그램으로, 이 응용 프로그램은 데이터 계층과 통신합니다.However, many real-world applications are multi-tier applications where a data source control might need to communicate to a business object which, in turn, communicates with the data layer. 이러한 상황에서는 ObjectDataSource가 청구서를 멋지게 채웁니다.In these situations, the ObjectDataSource fills the bill nicely. ObjectDataSource는 원본 개체와 함께 작동합니다.The ObjectDataSource works in conjunction with a source object. ObjectDataSource 컨트롤은 원본 개체의 인스턴스를 만들고, 지정된 메서드를 호출하고, 개체에 정적 메서드 대신 인스턴스 메서드가 있는 경우 단일 요청의 범위 내에서 개체 인스턴스를 모두 삭제합니다(Visual Basic에서 공유).The ObjectDataSource control will create an instance of the source object, call the specified method, and dispose of the object instance all within the scope of a single request, if your object has instance methods instead of static methods (Shared in Visual Basic). 따라서 개체는 상태 비저장이어야 합니다.Therefore, your object must be stateless. 즉, 개체는 단일 요청의 범위 내에서 필요한 모든 리소스를 획득하고 해제해야 합니다.That is, your object should acquire and release all required resources within the span of a single request. ObjectDataSource 컨트롤의 ObjectCreating 이벤트를 처리 하여 소스 개체를 만드는 방법을 제어할 수 있습니다.You can control how the source object is created by handling the ObjectCreating event of the ObjectDataSource control. 소스 개체의 인스턴스를 만든 다음 ObjectDataSourceEventArgs 클래스의 ObjectInstance 속성을 해당 인스턴스로 설정할 수 있습니다.You can create an instance of the source object, and then set the ObjectInstance property of the ObjectDataSourceEventArgs class to that instance. ObjectDataSource 컨트롤은 자체적으로 인스턴스를 만드는 대신 ObjectCreated 이벤트에서 생성된 인스턴스를 사용합니다.The ObjectDataSource control will use the instance that is created in the ObjectCreating event instead of creating an instance on its own.

ObjectDataSource 컨트롤의 원본 개체가 데이터를 검색하고 수정하기 위해 호출할 수 있는 공용 정적 메서드(Visual Basic에서 공유)를 노출하는 경우 ObjectDataSource 컨트롤은 해당 메서드를 직접 호출합니다.If the source object for an ObjectDataSource control exposes public static methods (Shared in Visual Basic) that can be called to retrieve and modify data, an ObjectDataSource control will call those methods directly. ObjectDataSource 컨트롤 메서드를 호출 하기 위해 소스 개체의 인스턴스를 만들어야 하는 경우 개체에는 매개 변수를 사용 하지 않는 공용 생성자가 포함 해야 합니다.If an ObjectDataSource control must create an instance of the source object in order to make method calls, the object must include a public constructor that takes no parameters. ObjectDataSource 컨트롤은 소스 개체의 새 인스턴스를 만들 때 이 생성자 호출합니다.The ObjectDataSource control will call this constructor when it creates a new instance of the source object.

원본 개체에 매개 변수가 없는 공용 생성자가 없는 경우 ObjectCreate 이벤트에서 ObjectDataSource 컨트롤에서 사용할 소스 개체의 인스턴스를 만들 수 있습니다.If the source object does not contain a public constructor without parameters, you can create an instance of the source object that will be used by the ObjectDataSource control in the ObjectCreating event.

개체 메서드 지정Specifying Object Methods

ObjectDataSource 컨트롤의 원본 개체에는 데이터를 선택, 삽입, 업데이트 또는 삭제하는 데 사용되는 여러 가지 메서드가 포함될 수 있습니다.The source object for an ObjectDataSource control can contain any number of methods that are used to select, insert, update, or delete data. 이러한 메서드는 ObjectDataSource 컨트롤의 SelectMethod, InsertMethod, UpdateMethod 또는 DeleteMethod 속성을 사용하여 식별되는 메서드 이름을 기반으로 ObjectDataSource 컨트롤에서 호출됩니다.These methods are called by the ObjectDataSource control based on the name of the method, as identified by using either the SelectMethod, InsertMethod, UpdateMethod, or DeleteMethod property of the ObjectDataSource control. 소스 개체에는 데이터 원본의 총 개체 수 수를 반환하는 SelectCountMethod 속성을 사용하여 ObjectDataSource 컨트롤에 의해 식별되는 선택적 SelectCount 메서드도 포함될 수 있습니다.The source object can also include an optional SelectCount method, which is identified by the ObjectDataSource control using the SelectCountMethod property, that returns the count of the total number of objects at the data source. ObjectDataSource 컨트롤은 Select 메서드가 호출된 후 페이징 할 때 사용할 데이터 원본의 총 레코드 수를 검색하기 위해 SelectCount 메서드를 호출합니다.The ObjectDataSource control will call the SelectCount method after a Select method has been called to retrieve the total number of records at the data source for use when paging.

데이터 원본 컨트롤을 사용하는 랩Lab Using Data Source Controls

연습 1 - SqlDataSource 컨트롤을 사용하여 데이터 표시Exercise 1 - Displaying Data with the SqlDataSource Control

다음 연습에서는 SqlDataSource 컨트롤을 사용하여 Northwind 데이터베이스에 연결합니다.The following exercise uses the SqlDataSource control to connect to the Northwind database. SQL Server 2000 인스턴스에서 Northwind 데이터베이스에 액세스할 수 있다고 가정합니다.It assumes that you have access to the Northwind database on a SQL Server 2000 instance.

  1. 새 ASP.NET 웹 사이트 만들기Create a new ASP.NET Web site.

  2. 새 web.config 파일을 추가합니다.Add a new web.config file.

    1. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 새 항목 추가를 클릭합니다.Right-click on the project in Solution Explorer and click Add New Item.
    2. 템플릿 목록에서 웹 구성 파일을 선택하고 추가를 클릭합니다.Choose Web Configuration File from the list of templates and click Add.
  3. <다음과 같이 연결> 문자열 섹션을 편집합니다.Edit the <connectionStrings> section as follows:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ConnectionStrings:Northwind%>"
        SelectCommand="SELECT * FROM Products">
    </asp:SqlDataSource>
    
  4. 코드 보기로 전환하고 다음과 같이 asp:SqlDataSource <> 컨트롤에 ConnectionString 특성 과 SelectCommand 특성을 추가합니다.Switch to Code view and add a ConnectionString attribute and a SelectCommand attribute to the <asp:SqlDataSource> control as follows:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ConnectionStrings:Northwind%>"
        SelectCommand="SELECT * FROM Products">
    </asp:SqlDataSource>
    
  5. 설계 보기에서 새 GridView 컨트롤을 추가합니다.From Design view, add a new GridView control.

  6. GridView 작업 메뉴에서 데이터 원본 선택 드롭다운에서 SqlDataSource1을 선택합니다.From the Choose Data Source dropdown in the GridView Tasks menu, choose SqlDataSource1.

  7. Default.aspx를 마우스 오른쪽 버튼으로 클릭하고 메뉴에서 브라우저에서 보기를 선택합니다.Right-click on Default.aspx and choose View in Browser from the menu. 저장하라는 메시지가 표시되면 예를 클릭합니다.Click Yes when prompted to save.

  8. GridView는 제품 테이블의 데이터를 표시합니다.The GridView displays the data from the Products table.

연습 2 - SqlDataSource 컨트롤로 데이터 편집Exercise 2 - Editing Data with the SqlDataSource Control

다음 연습에서는 선언적 구문을 사용하여 DropDownList 컨트롤을 데이터 바인딩하는 방법을 보여 주며 DropDownList 컨트롤에 표시되는 데이터를 편집할 수 있습니다.The following exercise demonstrates how to data bind a DropDownList control using the declarative syntax and allows you to edit the data presented in the DropDownList control.

  1. 설계 보기에서 Default.aspx에서 GridView 컨트롤을 삭제합니다.In Design view, delete the GridView control from Default.aspx.

    중요: 페이지에 SqlDataSource 컨트롤을 둡니다.Important: Leave the SqlDataSource control on the page.

  2. 디폴드.aspx에 드롭다운리스트 컨트롤을 추가합니다.Add a DropDownList control to Default.aspx.

  3. 소스 보기로 전환합니다.Switch to Source view.

  4. 다음과 같이 asp:DropDownList <> 컨트롤에 DataSourceId, DataTextField 및 DataValueField 특성을 추가합니다.Add a DataSourceId, DataTextField, and DataValueField attribute to the <asp:DropDownList> control as follows:

    <asp:DropDownList ID="ddlProducts" runat="server"
         DataSourceId="SqlDataSource1" DataTextField="ProductName"
         DataValueField="ProductID">
    </asp:DropDownList>
    
  5. Default.aspx를 저장하고 브라우저에서 볼 수 있습니다.Save Default.aspx and view it in the browser. 드롭다운목록에는 노스윈드 데이터베이스의 모든 제품이 포함되어 있습니다.Note that the DropDownList contains all of the products from the Northwind database.

  6. 브라우저를 닫습니다.Close the browser.

  7. Default.aspx의 소스 보기에서 드롭다운리스트 컨트롤 아래에 새 텍스트 상자 컨트롤을 추가합니다.In Source view of Default.aspx, add a new TextBox control below the DropDownList control. 텍스트 상자의 ID 속성을 txtProductName으로 변경합니다.Change the ID property of the TextBox to txtProductName.

  8. TextBox 컨트롤에서 새 단추 컨트롤을 추가합니다.Under the TextBox control, add a new Button control. 단추의 ID 속성을 btnUpdate로 변경하고 텍스트 속성을 제품 이름을 업데이트합니다.Change the ID property of the Button to btnUpdate and the Text property to Update Product Name.

  9. Default.aspx의 소스 보기에서 다음과 같이 UpdateCommand 속성과 두 개의 새 UpdateParameters를 SqlDataSource 태그에 추가합니다.In Source view of Default.aspx, add an UpdateCommand property and two new UpdateParameters to the SqlDataSource tag as follows:

    <asp:SqlDataSource ID="SqlDataSource1" runat="server"
        ConnectionString="<%$ConnectionStrings:Northwind%>"
        SelectCommand="SELECT * FROM Products"
        UpdateCommand="UPDATE Products SET ProductName=@ProductName WHERE ProductID=@ProductID">
          <UpdateParameters>
          <asp:ControlParameter Name="ProductName" 
            ControlID="txtProductName" PropertyName="Text" />
          <asp:ControlParameter Name="ProductID" 
            ControlID="ddlProducts" PropertyName="SelectedValue" />
    </asp:SqlDataSource>
    

    Note

    이 코드에는 두 가지 업데이트 매개 변수(ProductName 및 ProductID)가 추가되어 있습니다.Note that there are two update parameters (ProductName and ProductID) added in this code. 이러한 매개 변수는 txtProductName 텍스트 상자의 텍스트 속성과 ddlProducts 드롭다운 목록의 SelectedValue 속성에 매핑됩니다.These parameters are mapped to the Text property of the txtProductName TextBox and the SelectedValue property of the ddlProducts DropDownList.

  10. 디자인 보기로 전환하고 Button 컨트롤을 두 번 클릭하여 이벤트 처리기를 추가합니다.Switch to Design view and double-click on the Button control to add an event handler.

  11. btnUpdate_클릭 코드에 다음 코드를 추가합니다.Add the following code to the btnUpdate_Click code:

    SqlDataSource1.Update();
    
  12. Default.aspx를 마우스 오른쪽 버튼으로 클릭하고 브라우저에서 볼 수 있도록 선택합니다.Right-click on Default.aspx and choose to view it in the browser. 모든 변경 내용을 저장하라는 메시지가 표시되면 예를 클릭합니다.Click Yes when prompted to save all changes.

  13. ASP.NET 2.0 부분 클래스는 런타임에 컴파일을 허용합니다.ASP.NET 2.0 partial classes allow for compilation at runtime. 코드 변경 내용이 적용되는지 확인하기 위해 응용 프로그램을 빌드할 필요는 없습니다.It is not necessary to build an application in order to see code changes take effect.

  14. 드롭다운 목록에서 제품을 선택합니다.Select a product from the DropDownList.

  15. TextBox에서 선택한 제품의 새 이름을 입력한 다음 업데이트 단추를 클릭합니다.Enter a new name for the selected product in the TextBox and then click the Update button.

  16. 제품 이름이 데이터베이스에서 업데이트됩니다.The product name is updated in the database.

연습 3 개체 데이터 소스 컨트롤 사용Exercise 3 Using the ObjectDataSource Control

이 연습에서는 ObjectDataSource 컨트롤 및 소스 개체를 사용하여 Northwind 데이터베이스와 상호 작용하는 방법을 보여 줍니다.This exercise will demonstrate how to use the ObjectDataSource control and a source object to interact with the Northwind database.

  1. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 새 항목 추가를 클릭합니다.Right-click on the project in Solution Explorer and click on Add New Item.

  2. 템플릿 목록에서 웹 양식을 선택합니다.Select Web Form in the templates list. 이름을 object.aspx로 변경하고 추가를 클릭합니다.Change the name to object.aspx and click Add.

  3. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 새 항목 추가를 클릭합니다.Right-click on the project in Solution Explorer and click on Add New Item.

  4. 템플릿 목록에서 클래스를 선택합니다.Select Class in the templates list. 클래스 이름을 변경하여 NorthwindData.cs 추가를 클릭합니다.Change the name of the class to NorthwindData.cs and click Add.

  5. 앱_코드 폴더에 클래스를 추가하라는 메시지가 표시되면 예를 클릭합니다.Click Yes when prompted to add the class to the App_Code folder.

  6. NorthwindData.cs 파일에 다음 코드를 추가합니다.Add the following code to the NorthwindData.cs file:

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Data.SqlClient;
    public class NorthwindData {
        private string _connectionString;
        public NorthwindData() {
            Initialize();
        }
    
        private void Initialize() {
            if (ConfigurationManager.ConnectionStrings["Northwind"] == null ||
                ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString.Trim() == "") {
                    throw new Exception("A connection string named 'Northwind' with " +
                    "a valid connection string must exist in the <connectionStrings> " +
                    "configuration section for the application.");
            }
            _connectionString = ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
        }
    
        public DataTable GetAllEmployees(string sortColumns, int startRecord, int maxRecords) {
            VerifySortColumns(sortColumns);
            string sqlCmd = "SELECT EmployeeID, LastName, FirstName, Address, " +
                "City, Region, PostalCode FROM Employees ";
            if (sortColumns.Trim() == "")
                sqlCmd += "ORDER BY EmployeeID";
            else
                sqlCmd += "ORDER BY " + sortColumns;
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlDataAdapter da = new SqlDataAdapter(sqlCmd, conn);
            DataSet ds = new DataSet();
            try {
                conn.Open();
                da.Fill(ds, startRecord, maxRecords, "Employees");
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
            return ds.Tables["Employees"];
        }
    
        public int SelectCount() {
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM Employees", conn);
            int result = 0;
    
            try {
                conn.Open();
                result = (int)cmd.ExecuteScalar();
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
            return result;
        }
    
        //////////
        // Verify that only valid columns are specified in the sort expression to
        // avoid a SQL Injection attack.
        private void VerifySortColumns(string sortColumns) {
            if (sortColumns.ToLowerInvariant().EndsWith(" desc"))
                sortColumns = sortColumns.Substring(0, sortColumns.Length - 5);
            string[] columnNames = sortColumns.Split(',');
            foreach (string columnName in columnNames) {
                switch (columnName.Trim().ToLowerInvariant()) {
                    case "employeeid":
                        break;
                    case "lastname":
                        break;
                    case "firstname":
                        break;
                    case "":
                        break;
                    default:
                        throw new ArgumentException("SortColumns contains an " +
                            "invalid column name.");
                        break;
                }
            }
        }
    
        // Select an employee.
        public DataTable GetEmployee(int EmployeeID) {
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlDataAdapter da =
                new SqlDataAdapter("SELECT EmployeeID, LastName, FirstName, " +
                "Address, City, Region, PostalCode " +
                " FROM Employees WHERE EmployeeID = @EmployeeID", conn);
            da.SelectCommand.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;
            DataSet ds = new DataSet();
            try {
                conn.Open();
                da.Fill(ds, "Employees");
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
    
            return ds.Tables["Employees"];
        }
    
        // Delete the Employee by ID.
        public int DeleteEmployee(int EmployeeID) {
             SqlConnection conn = new SqlConnection(_connectionString);
             SqlCommand cmd = new SqlCommand("DELETE FROM Employees WHERE " +
                 "EmployeeID = @EmployeeID", conn);
             cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;
             int result = 0;
             try {
                 conn.Open();
                 result = cmd.ExecuteNonQuery();
             } catch (SqlException e) {
                 // Handle exception.
             } finally {
                 conn.Close();
             }
    
             return result;
         }
    
         // Update the Employee by original ID.
         public int UpdateEmployee(int EmployeeID, string LastName, string FirstName,
             string Address, string City, string Region,
             string PostalCode) {
             if (String.IsNullOrEmpty(FirstName))
                 throw new ArgumentException("FirstName cannot be null or an empty string.");
             if (String.IsNullOrEmpty(LastName))
                 throw new ArgumentException("LastName cannot be null or an empty string.");
             if (Address == null) { Address = String.Empty; }
             if (City == null) { City = String.Empty; }
             if (Region == null) { Region = String.Empty; }
             if (PostalCode == null) { PostalCode = String.Empty; }
    
             SqlConnection conn = new SqlConnection(_connectionString);
             SqlCommand cmd = new SqlCommand("UPDATE Employees " +
                 " SET FirstName=@FirstName, " +
                 "LastName=@LastName, " +
                 "Address=@Address, City=@City, " +
                 "Region=@Region, " +
                 "PostalCode=@PostalCode " +
                 "WHERE EmployeeID=@EmployeeID", conn);
             cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 10).Value = FirstName;
             cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 20).Value = LastName;
             cmd.Parameters.Add("@Address", SqlDbType.VarChar, 60).Value = Address;
             cmd.Parameters.Add("@City", SqlDbType.VarChar, 15).Value = City;
             cmd.Parameters.Add("@Region", SqlDbType.VarChar, 15).Value = Region;
             cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
             cmd.Parameters.Add("@EmployeeID", SqlDbType.Int).Value = EmployeeID;
    
             int result = 0;
             try {
                 conn.Open();
                 result = cmd.ExecuteNonQuery();
             } catch (SqlException e) {
                 // Handle exception.
             } finally {
                 conn.Close();
             }
    
             return result;
        }
    
        // Insert an Employee.
        public int InsertEmployee(string LastName, string FirstName,
            string Address, string City, string Region,
            string PostalCode) {
            if (String.IsNullOrEmpty(FirstName))
                throw new ArgumentException("FirstName cannot be null or an empty string.");
            if (String.IsNullOrEmpty(LastName))
                throw new ArgumentException("LastName cannot be null or an empty string.");
            if (Address == null) { Address = String.Empty; }
            if (City == null) { City = String.Empty; }
            if (Region == null) { Region = String.Empty; }
            if (PostalCode == null) { PostalCode = String.Empty; }
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand("INSERT INTO Employees " +
                " (FirstName, LastName, Address, " +
                " City, Region, PostalCode) " +
                " Values(@FirstName, @LastName, " +
                "@Address, @City, @Region, @PostalCode); " +
                "SELECT @EmployeeID = SCOPE_IDENTITY()", conn);
    
            cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 10).Value = FirstName;
            cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 20).Value = LastName;
            cmd.Parameters.Add("@Address", SqlDbType.VarChar, 60).Value = Address;
            cmd.Parameters.Add("@City", SqlDbType.VarChar, 15).Value = City;
            cmd.Parameters.Add("@Region", SqlDbType.VarChar, 15).Value = Region;
            cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
            SqlParameter p = cmd.Parameters.Add("@EmployeeID", SqlDbType.Int);
                p.Direction = ParameterDirection.Output;
            int newEmployeeID = 0;
            try {
                conn.Open();
                cmd.ExecuteNonQuery();
                newEmployeeID = (int)p.Value;
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
    
            return newEmployeeID;
        }
    
        //
        // Methods that support Optimistic Concurrency checks.
        //
        // Delete the Employee by ID.
        public int DeleteEmployee(int original_EmployeeID, string original_LastName,
            string original_FirstName, string original_Address,
            string original_City, string original_Region,
            string original_PostalCode) {
    
            if (String.IsNullOrEmpty(original_FirstName))
                throw new ArgumentException("FirstName cannot be null or an empty string.");
            if (String.IsNullOrEmpty(original_LastName))
                throw new ArgumentException("LastName cannot be null or an empty string.");
            if (original_Address == null) { original_Address = String.Empty; }
            if (original_City == null) { original_City = String.Empty; }
            if (original_Region == null) { original_Region = String.Empty; }
            if (original_PostalCode == null) { original_PostalCode = String.Empty; }
            string sqlCmd = "DELETE FROM Employees WHERE EmployeeID = " + @original_EmployeeID
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand(sqlCmd, conn);
            cmd.Parameters.Add("@original_EmployeeID",
                SqlDbType.Int).Value = original_EmployeeID;
            cmd.Parameters.Add("@original_FirstName",
                SqlDbType.VarChar, 10).Value = original_FirstName;
            cmd.Parameters.Add("@original_LastName",
                SqlDbType.VarChar, 20).Value = original_LastName;
            cmd.Parameters.Add("@original_Address",
                SqlDbType.VarChar, 60).Value = original_Address;
            cmd.Parameters.Add("@original_City",
                SqlDbType.VarChar, 15).Value = original_City;
            cmd.Parameters.Add("@original_Region",
                SqlDbType.VarChar, 15).Value = original_Region;
            cmd.Parameters.Add("@original_PostalCode",
                SqlDbType.VarChar, 10).Value = original_PostalCode;
    
            int result = 0;
            try {
                conn.Open();
                result = cmd.ExecuteNonQuery();
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
    
            return result;
        }
    
        // Update the Employee by original ID.
        public int UpdateEmployee(string LastName, string FirstName,
            string Address, string City, string Region,
            string PostalCode, int original_EmployeeID,
            string original_LastName, string original_FirstName,
            string original_Address, string original_City,
            string original_Region, string original_PostalCode) {
    
            if (String.IsNullOrEmpty(FirstName))
                throw new ArgumentException("FirstName cannot be null or an empty string.");
            if (String.IsNullOrEmpty(LastName))
                throw new ArgumentException("LastName cannot be null or an empty string.");
            if (Address == null) { Address = String.Empty; }
            if (City == null) { City = String.Empty; }
            if (Region == null) { Region = String.Empty; }
            if (PostalCode == null) { PostalCode = String.Empty; }
            if (original_Address == null) { original_Address = String.Empty; }
            if (original_City == null) { original_City = String.Empty; }
            if (original_Region == null) { original_Region = String.Empty; }
            if (original_PostalCode == null) { original_PostalCode = String.Empty; }
    
            string sqlCmd = "UPDATE Employees " +
                " SET FirstName = @FirstName, LastName = @LastName, " +
                " Address = @Address, City = @City, Region = @Region, " +
                " PostalCode = @PostalCode " +
                " WHERE EmployeeID = @original_EmployeeID";
    
            SqlConnection conn = new SqlConnection(_connectionString);
            SqlCommand cmd = new SqlCommand(sqlCmd, conn);
            cmd.Parameters.Add("@FirstName", SqlDbType.VarChar, 10).Value = FirstName;
            cmd.Parameters.Add("@LastName", SqlDbType.VarChar, 20).Value = LastName;
            cmd.Parameters.Add("@Address", SqlDbType.VarChar, 60).Value = Address;
            cmd.Parameters.Add("@City", SqlDbType.VarChar, 15).Value = City;
            cmd.Parameters.Add("@Region", SqlDbType.VarChar, 15).Value = Region;
            cmd.Parameters.Add("@PostalCode", SqlDbType.VarChar, 10).Value = PostalCode;
            cmd.Parameters.Add("@original_EmployeeID",
                SqlDbType.Int).Value = original_EmployeeID;
            cmd.Parameters.Add("@original_FirstName",
                SqlDbType.VarChar, 10).Value = original_FirstName;
            cmd.Parameters.Add("@original_LastName",
                SqlDbType.VarChar, 20).Value = original_LastName;
            cmd.Parameters.Add("@original_Address",
                SqlDbType.VarChar, 60).Value = original_Address;
            cmd.Parameters.Add("@original_City",
                SqlDbType.VarChar, 15).Value = original_City;
            cmd.Parameters.Add("@original_Region",
                SqlDbType.VarChar, 15).Value = original_Region;
            cmd.Parameters.Add("@original_PostalCode",
                SqlDbType.VarChar, 10).Value = original_PostalCode;
    
            int result = 0;
    
            try {
                conn.Open();
                result = cmd.ExecuteNonQuery();
            } catch (SqlException e) {
                // Handle exception.
            } finally {
                conn.Close();
            }
            return result;
        }
    }
    
  7. object.aspx의 소스 보기에 다음 코드를 추가합니다.Add the following code to the Source view of object.aspx:

    <%@ Page language="C#" %>
    <script RunAt="server">
    void EmployeesDetailsView_ItemInserted(Object sender, DetailsViewInsertedEventArgs e) {
        EmployeesGridView.DataBind();
    }
    
    void EmployeesDetailsView_ItemUpdated(Object sender, DetailsViewUpdatedEventArgs e) {
        EmployeesGridView.DataBind();
    }
    
    void EmployeesDetailsView_ItemDeleted(Object sender, DetailsViewDeletedEventArgs e) {
        EmployeesGridView.DataBind();
    }
    void EmployeesGridView_OnSelectedIndexChanged(object sender, EventArgs e) {
        EmployeeDetailsObjectDataSource.SelectParameters["EmployeeID"].DefaultValue =
            EmployeesGridView.SelectedDataKey.Value.ToString();
        EmployeesDetailsView.DataBind();
    }
    void EmployeeDetailsObjectDataSource_OnInserted(object sender,
        ObjectDataSourceStatusEventArgs e) {
    
        EmployeeDetailsObjectDataSource.SelectParameters["EmployeeID"].DefaultValue =
            e.ReturnValue.ToString();
        EmployeesDetailsView.DataBind();
    }
    void EmployeeDetailsObjectDataSource_OnUpdated(object sender,
        ObjectDataSourceStatusEventArgs e) {
    
        if ((int)e.ReturnValue == 0)
            Msg.Text = "Employee was not updated. Please try again.";
    }
    void EmployeeDetailsObjectDataSource_OnDeleted(object sender,
        ObjectDataSourceStatusEventArgs e) {
    
        if ((int)e.ReturnValue == 0)
            Msg.Text = "Employee was not deleted. Please try again.";
    }
    void Page_Load() {
        Msg.Text = "";
    }
    </script>
    <html>
      <body>
        <form id="Form1" runat="server">
          <h3>ObjectDataSource Example</h3>
          <asp:Label id="Msg" runat="server" ForeColor="Red" />
          <asp:ObjectDataSource
              ID="EmployeesObjectDataSource"
              runat="server"
              TypeName="NorthwindData"
              SortParameterName="SortColumns"
              EnablePaging="true"
              SelectCountMethod="SelectCount"
              StartRowIndexParameterName="StartRecord"
              MaximumRowsParameterName="MaxRecords"
              SelectMethod="GetAllEmployees" >
          </asp:ObjectDataSource>
          <asp:ObjectDataSource
              ID="EmployeeDetailsObjectDataSource"
              runat="server"
              TypeName="NorthwindData"
              ConflictDetection="CompareAllValues"
              OldValuesParameterFormatString="{0}"
              SelectMethod="GetEmployee"
              InsertMethod="InsertEmployee"
              UpdateMethod="UpdateEmployee"
              DeleteMethod="DeleteEmployee"
              OnInserted="EmployeeDetailsObjectDataSource_OnInserted"
              OnUpdated="EmployeeDetailsObjectDataSource_OnUpdated"
              OnDeleted="EmployeeDetailsObjectDataSource_OnDeleted">
              <SelectParameters>
                  <asp:Parameter Name="EmployeeID" Type="Int32" />
              </SelectParameters>
          </asp:ObjectDataSource>
          <table cellspacing="10">
            <tr>
              <td valign="top">
                <asp:GridView ID="EmployeesGridView"
                    DataSourceID="EmployeesObjectDataSource"
                    AutoGenerateColumns="false"
                    AllowSorting="true"
                    AllowPaging="true"
                    PageSize="5"
                    DataKeyNames="EmployeeID"
                    OnSelectedIndexChanged="EmployeesGridView_OnSelectedIndexChanged"
                    RunAt="server">
                    <HeaderStyle backcolor="lightblue" forecolor="black"/>
                    <Columns>
                    <asp:ButtonField Text="Details..."
                    HeaderText="Show Details"
                    CommandName="Select"/>
    
                    <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID"
                    SortExpression="EmployeeID" />
                    <asp:BoundField DataField="FirstName" HeaderText="First Name"
                    SortExpression="FirstName" />
                    <asp:BoundField DataField="LastName" HeaderText="Last Name"
                    SortExpression="LastName, FirstName" />
                    </Columns>
                </asp:GridView>
              </td>
              <td valign="top">
                <asp:DetailsView ID="EmployeesDetailsView"
                    DataSourceID="EmployeeDetailsObjectDataSource"
                    AutoGenerateRows="false"
                    EmptyDataText="No records."
                    DataKeyNames="EmployeeID"
                    Gridlines="Both"
                    AutoGenerateInsertButton="true"
                    AutoGenerateEditButton="true"
                    AutoGenerateDeleteButton="true"
                    OnItemInserted="EmployeesDetailsView_ItemInserted"
                    OnItemUpdated="EmployeesDetailsView_ItemUpdated"
                    OnItemDeleted="EmployeesDetailsView_ItemDeleted"
                    RunAt="server">
                    <HeaderStyle backcolor="Navy" forecolor="White"/>
                    <RowStyle backcolor="White"/>
                    <AlternatingRowStyle backcolor="LightGray"/>
                    <EditRowStyle backcolor="LightCyan"/>
                    <Fields>
                        <asp:BoundField DataField="EmployeeID" HeaderText="Employee ID"
                            InsertVisible="False" ReadOnly="true"/>
                        <asp:BoundField DataField="FirstName" HeaderText="First Name"/>
                        <asp:BoundField DataField="LastName" HeaderText="Last Name"/>
                        <asp:BoundField DataField="Address" HeaderText="Address"/>
                        <asp:BoundField DataField="City" HeaderText="City"/>
                        <asp:BoundField DataField="Region" HeaderText="Region"/>
                        <asp:BoundField DataField="PostalCode" HeaderText="Postal Code"/>
                    </Fields>
                  </asp:DetailsView>
                </td>
              </tr>
            </table>
          </form>
        </body>
      </html>
    
  8. 모든 파일을 저장하고 object.aspx를 찾아봅금.Save all files and browse object.aspx.

  9. 세부 정보를 보고, 직원을 편집하고, 직원을 추가하고, 직원을 삭제하여 인터페이스와 상호 작용합니다.Interact with the interface by viewing details, editing employees, adding employees, and deleting employees.