TableAdapter’ı JOIN Kullanacak Biçimde Güncelleştirme (C#)Updating the TableAdapter to Use JOINs (C#)

Scott Mitchell tarafındanby Scott Mitchell

Kodu indirin veya PDF 'yi indirinDownload Code or Download PDF

Bir veritabanıyla çalışırken, birden çok tabloya yayılan veriler istemek yaygındır.When working with a database it is common to request data that is spread across multiple tables. İki farklı tablodan verileri almak için bağıntılı bir alt sorgu veya bir JOIN işlemi kullanabilirsiniz.To retrieve data from two different tables we can use either a correlated subquery or a JOIN operation. Bu öğreticide, ana sorgusunda JOIN içeren bir TableAdapter oluşturmayı aramadan önce bağıntılı alt sorguları ve JOIN sözdizimini karşılaştırıyoruz.In this tutorial we compare correlated subqueries and the JOIN syntax before looking at how to create a TableAdapter that includes a JOIN in its main query.

GirişIntroduction

İlişkisel veritabanlarında, çalışma konusunda ilgilendiğiniz veriler genellikle birden çok tablo arasında yayılır.With relational databases the data we are interested in working with is often spread across multiple tables. Örneğin, ürün bilgilerini görüntülerken her bir ürüne karşılık gelen her bir kategori ve sağlayıcı adını listelemek istiyoruz.For example, when displaying product information we likely want to list each product s corresponding category and supplier s names. Products tabloda CategoryID ve SupplierID değerleri bulunur, ancak gerçek kategori ve tedarikçi adları sırasıyla Categories ve Suppliers tablolarında bulunur.The Products table has CategoryID and SupplierID values, but the actual category and supplier names are in the Categories and Suppliers tables, respectively.

Başka bir ilişkili tablodan bilgi almak için, bağıntılı alt sorgular veya JOINskullanabilirsiniz.To retrieve information from another, related table, we can either use correlated subqueries or JOINs. Bağıntılı alt sorgu, dış sorgudaki sütunlara başvuran iç içe bir SELECT sorgusudur.A correlated subquery is a nested SELECT query that references columns in the outer query. Örneğin, veri erişim katmanı oluşturma öğreticisinde, her ürün için kategori ve Tedarikçi adlarını döndürmek üzere ProductsTableAdapter s ana sorgusunda iki bağıntılı alt sorgu kullandık.For example, in the Creating a Data Access Layer tutorial we used two correlated subqueries in the ProductsTableAdapter s main query to return the category and supplier names for each product. JOIN, iki farklı tablodan ilgili satırları birleştiren bir SQL yapısıdır.A JOIN is a SQL construct that merges related rows from two different tables. Her ürünle birlikte kategori bilgilerini göstermek için SqlDataSource denetim öğreticisi Ile verileri sorgulama JOIN kullandık.We used a JOIN in the Querying Data with the SqlDataSource Control tutorial to display category information alongside each product.

JOIN s 'yi TableAdapters ile kullanmanın yanı sıra, ilişkili INSERT, UPDATEve DELETE deyimlerini otomatik olarak oluşturmak için TableAdapter s sihirbazının sınırlamalarından kaynaklanır.The reason we have abstained from using JOIN s with the TableAdapters is because of limitations in the TableAdapter s wizard to auto-generate corresponding INSERT, UPDATE, and DELETE statements. Daha belirgin bir şekilde, TableAdapter s ana sorgusu herhangi bir JOIN s içeriyorsa, TableAdapter InsertCommand, UpdateCommandve DeleteCommand özellikleri için geçici SQL deyimlerini veya saklı yordamları otomatik olarak oluşturamaz.More specifically, if the TableAdapter s main query contains any JOIN s, the TableAdapter cannot auto-create the ad-hoc SQL statements or stored procedures for its InsertCommand, UpdateCommand, and DeleteCommand properties.

Bu öğreticide, ana sorgusunda JOIN s 'yi içeren bir TableAdapter oluşturmayı keşfetmeye başlamadan önce bağıntılı alt sorguları ve JOIN s 'leri daha fazla karşılaştıracağız.In this tutorial we will briefly compare and contrast correlated subqueries and JOIN s before exploring how to create a TableAdapter that includes JOIN s in its main query.

Bağıntılı alt sorgular veJOIN s karşılaştırması ve karşıtComparing and Contrasting Correlated Subqueries andJOIN s

Northwind veri kümesindeki ilk öğreticide oluşturulan ProductsTableAdapter, her bir ürüne karşılık gelen her bir kategoriyi ve tedarikçi adını geri getirmek için bağıntılı alt sorguları kullandığını hatırlayın.Recall that the ProductsTableAdapter created in the first tutorial in the Northwind DataSet uses correlated subqueries to bring back each product s corresponding category and supplier name. ProductsTableAdapter s ana sorgusu aşağıda gösterilmiştir.The ProductsTableAdapter s main query is shown below.

SELECT ProductID, ProductName, SupplierID, CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = 
            Products.CategoryID) as CategoryName, 
       (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = 
            Products.SupplierID) as SupplierName
FROM Products

İki bağıntılı alt sorgu-(SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) ve (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID)-, dış SELECT deyimlerinin sütun listesinde ek bir sütun olarak her ürün için tek bir değer döndüren SELECT sorgulardır.The two correlated subqueries - (SELECT CategoryName FROM Categories WHERE Categories.CategoryID = Products.CategoryID) and (SELECT CompanyName FROM Suppliers WHERE Suppliers.SupplierID = Products.SupplierID) - are SELECT queries that return a single value per product as an additional column in the outer SELECT statement s column list.

Alternatif olarak, bir JOIN her ürün tedarikçisine ve kategori adına döndürmek için de kullanılabilir.Alternatively, a JOIN can be used to return each product s supplier and category name. Aşağıdaki sorgu yukarıdaki ile aynı çıktıyı döndürür, ancak alt sorgular yerine JOIN s kullanır:The following query returns the same output as the above one, but uses JOIN s in place of subqueries:

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

JOIN, bir tablodaki kayıtları, bazı ölçütlere göre başka bir tablodaki kayıtlarla birleştirir.A JOIN merges the records from one table with records from another table based on some criteria. Yukarıdaki sorguda, örneğin, LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID her ürün kaydını CategoryID değeri ürün s CategoryID değeri ile eşleşen kategori kaydıyla birleştirmeye SQL Server söyler.In the above query, for example, the LEFT JOIN Categories ON Categories.CategoryID = Products.CategoryID instructs SQL Server to merge each product record with the category record whose CategoryID value matches the product s CategoryID value. Birleştirilmiş sonuç, her ürün için karşılık gelen kategori alanlarıyla (CategoryName) çalışmamızı sağlar.The merged result allows us to work with the corresponding category fields for each product (such as CategoryName).

Note

JOIN s 'ler, ilişkisel veritabanlarından veri sorgulanırken yaygın olarak kullanılır.JOIN s are commonly used when querying data from relational databases. JOIN söz dizimine yeni bir bit kullanıyorsanız veya kullanımı için bir bit kullanmanız gerekiyorsa, w3 okullarından SQL JOIN öğreticisini önerdim.If you are new to the JOIN syntax or need to brush up a bit on its usage, I d recommend the SQL Join tutorial at W3 Schools. Ayrıca, SQL Books Online'ın JOIN temel bilgiler ve alt sorgu temelleri bölümleri de okunuyor.Also worth reading are the JOIN Fundamentals and Subquery Fundamentals sections of the SQL Books Online.

JOIN s ve bağıntılı alt sorgular her ikisi de diğer tablolardan ilgili verileri almak için kullanıldığından, birçok geliştirici kafa çekmesini ve hangi yaklaşımın kullanılacağını merak ediyor.Since JOIN s and correlated subqueries can both be used to retrieve related data from other tables, many developers are left scratching their heads and wondering which approach to use. En çok kabaca aynı şeyi söylediği için, daha önce sundum olan tüm SQL Gurus 'ları, SQL Server kabaca özdeş yürütme planları üretecektir.All of the SQL gurus I ve talked to have said roughly the same thing, that it doesn t really matter performance-wise as SQL Server will produce roughly identical execution plans. Bu durumda, sizin ve takımınızın en rahat olduğu tekniğin kullanılması önerilir.Their advice, then, is to use the technique that you and your team are most comfortable with. Bu uzmanlardan sonra bu uzmanlar, bağıntılı alt sorgular üzerinde JOIN s tercihini hemen ifade ettikten sonra ele aldığını belirtir.It merits noting that after imparting this advice these experts immediately express their preference of JOIN s over correlated subqueries.

Yazılan veri kümelerini kullanarak bir veri erişim katmanı oluştururken araçlar, alt sorgular kullanılırken daha iyi çalışır.When building a Data Access Layer using Typed DataSets, the tools work better when using subqueries. Özellikle, TableAdapter s Sihirbazı, ana sorgu herhangi bir JOIN s içeriyorsa karşılık gelen INSERT, UPDATEve DELETE deyimlerini otomatik olarak oluşturmaz, ancak bağıntılı alt sorgular kullanıldığında bu deyimleri otomatik olarak oluşturur.In particular, the TableAdapter s wizard will not auto-generate corresponding INSERT, UPDATE, and DELETE statements if the main query contains any JOIN s, but will auto-generate these statements when correlated subqueries are used.

Bu eksiklikleri araştırmak için ~/App_Code/DAL klasöründe geçici olarak yazılmış bir veri kümesi oluşturun.To explore this shortcoming, create a temporary Typed DataSet in the ~/App_Code/DAL folder. TableAdapter Yapılandırma Sihirbazı sırasında, geçici SQL deyimlerini kullanmayı seçin ve aşağıdaki SELECT sorguyu girin (bkz. Şekil 1):During the TableAdapter Configuration wizard, choose to use ad-hoc SQL statements and enter the following SELECT query (see Figure 1):

SELECT ProductID, ProductName, Products.SupplierID, Products.CategoryID, 
       QuantityPerUnit, UnitPrice, UnitsInStock, UnitsOnOrder, 
       ReorderLevel, Discontinued,
       Categories.CategoryName, 
       Suppliers.CompanyName as SupplierName
FROM Products
    LEFT JOIN Categories ON
        Categories.CategoryID = Products.CategoryID
    LEFT JOIN Suppliers ON
        Suppliers.SupplierID = Products.SupplierID

birleşimler Içeren bir ana sorgu girinEnter a Main Query that Contains JOINs

Şekil 1: JOIN s Içeren bir ana sorgu girin (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 1: Enter a Main Query that Contains JOIN s (Click to view full-size image)

Varsayılan olarak TableAdapter, ana sorguya göre otomatik olarak INSERT, UPDATEve DELETE deyimlerini oluşturacaktır.By default, the TableAdapter will automatically create INSERT, UPDATE, and DELETE statements based on the main query. Gelişmiş düğmesine tıklarsanız, bu özelliğin etkin olduğunu görebilirsiniz.If you click the Advanced button you can see that this feature is enabled. Bu ayara rağmen, ana sorgu bir JOINiçerdiğinden TableAdapter INSERT, UPDATEve DELETE deyimlerini oluşturamayacak.Despite this setting, the TableAdapter will not be able to create the INSERT, UPDATE, and DELETE statements because the main query contains a JOIN.

Birleşimler Içeren bir ana sorgu girin

Şekil 2: JOIN s Içeren bir ana sorgu girinFigure 2: Enter a Main Query that Contains JOIN s

Sihirbazı tamamladığınızda son ' a tıklayın.Click Finish to complete the wizard. Bu noktada, DataSet s Designer, SELECT Query s sütun listesinde döndürülen her bir alan için sütun içeren bir DataTable içeren tek bir TableAdapter içerir.At this point your DataSet s Designer will include a single TableAdapter with a DataTable with columns for each of the fields returned in the SELECT query s column list. Bu, Şekil 3 ' ün gösterdiği gibi CategoryName ve SupplierNameiçerir.This includes the CategoryName and SupplierName, as Figure 3 shows.

DataTable, sütun listesinde döndürülen her alan için bir sütun Içerir

Şekil 3: DataTable, sütun listesinde döndürülen her alan Için bir sütun içerirFigure 3: The DataTable Includes a Column for Each Field Returned in the Column List

DataTable uygun sütunlara sahip olsa da TableAdapter InsertCommand, UpdateCommandve DeleteCommand özellikleri için değerler eksiktir.While the DataTable has the appropriate columns, the TableAdapter lacks values for its InsertCommand, UpdateCommand, and DeleteCommand properties. Bunu onaylamak için, tasarımcıda TableAdapter 'a tıklayın ve ardından Özellikler penceresi gidin.To confirm this, click on the TableAdapter in the Designer and then go to the Properties window. InsertCommand, UpdateCommandve DeleteCommand özelliklerinin (None) olarak ayarlandığını görürsünüz.There you will see that the InsertCommand, UpdateCommand, and DeleteCommand properties are set to (None) .

InsertCommand, UpdateCommand ve DeleteCommand özellikleri (yok) olarak ayarlanırThe InsertCommand, UpdateCommand, and DeleteCommand Properties are Set to (None)

Şekil 4: InsertCommand, UpdateCommandve DeleteCommand özellikleri (yok) olarak ayarlanır (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 4: The InsertCommand, UpdateCommand, and DeleteCommand Properties are Set to (None) (Click to view full-size image)

Bu eksiklikleri geçici olarak çözmek için, Özellikler penceresi aracılığıyla InsertCommand, UpdateCommandve DeleteCommand özelliklerinin SQL deyimlerini ve parametrelerini el ile sağlayabiliriz.To work around this shortcoming, we can manually provide the SQL statements and parameters for the InsertCommand, UpdateCommand, and DeleteCommand properties via the Properties window. Alternatif olarak, TableAdapter s ana sorgusunu hiçbir JOIN s 'yi içerecek şekilde yapılandırarak başlayabiliriz.Alternatively, we could start by configuring the TableAdapter s main query to not include any JOIN s. Bu, INSERT, UPDATEve DELETE deyimlerinin ABD için otomatik olarak oluşturulmasını sağlar.This will allow the INSERT, UPDATE, and DELETE statements to be auto-generated for us. Sihirbazı tamamladıktan sonra, JOIN sözdizimini içermesi için TableAdapter s SelectCommand Özellikler penceresi el ile güncelleştirebilirsiniz.After completing the wizard, we could then manually update the TableAdapter s SelectCommand from the Properties window so that it includes the JOIN syntax.

Bu yaklaşım çalışırken, TableAdapter s ana sorgusunun sihirbaz aracılığıyla yeniden yapılandırıldığı, otomatik olarak oluşturulan INSERT, UPDATEve DELETE deyimlerinin yeniden oluşturulduğu her seferinde geçici SQL sorguları kullanılırken çok Brittle.While this approach works, it is very brittle when using ad-hoc SQL queries because any time the TableAdapter s main query is re-configured through the wizard, the auto-generated INSERT, UPDATE, and DELETE statements are recreated. Diğer bir deyişle, TableAdapter 'a sağ tıklıyoruz, bağlam menüsünden Yapılandır ' ı seçip Sihirbazı yeniden tamamladıktan sonra, daha sonra yaptığımız tüm özelleştirmeler kaybedilir.That means all of the customizations we later made would be lost if we right-clicked on the TableAdapter, chose Configure from the context menu, and completed the wizard again.

TableAdapter s otomatik olarak oluşturulan INSERT, UPDATEve DELETE deyimlerinin britttayeti, neyse ki geçici SQL deyimleriyle sınırlıdır.The brittleness of the TableAdapter s auto-generated INSERT, UPDATE, and DELETE statements is, fortunately, limited to ad-hoc SQL statements. TableAdapter saklı yordamlar kullanıyorsa, SelectCommand, InsertCommand, UpdateCommandveya DeleteCommand saklı yordamları özelleştirebilir ve, saklı yordamların değiştirilmesini sağlamak zorunda kalmadan TableAdapter Yapılandırma Sihirbazı 'nı yeniden çalıştırabilirsiniz.If your TableAdapter uses stored procedures, you can customize the SelectCommand, InsertCommand, UpdateCommand, or DeleteCommand stored procedures and re-run the TableAdapter Configuration wizard without having to fear that the stored procedures will be modified.

Sonraki birkaç adımda, başlangıçta, ilgili INSERT, Update ve delete saklı yordamlarının otomatik olarak üretilebilmesi için JOIN s 'yi atlayacak bir ana sorgu kullanan bir TableAdapter oluşturacağız.Over the next several steps we will create a TableAdapter that, initially, uses a main query that omits any JOIN s so that the corresponding insert, update, and delete stored procedures will be auto-generated. Daha sonra, ilgili tablolardan ek sütunları döndüren bir JOIN kullanması için SelectCommand güncelleştireceğiz.We will then update the SelectCommand so that uses a JOIN that returns additional columns from related tables. Son olarak, karşılık gelen bir Iş mantığı katman sınıfı oluşturacağız ve TableAdapter 'ı bir ASP.NET Web sayfasında kullanmayı gösteririz.Finally, we'll create a corresponding Business Logic Layer class and demonstrate using the TableAdapter in an ASP.NET web page.

1. Adım: Basitleştirilmiş ana sorgu kullanarak TableAdapter oluşturmaStep 1: Creating the TableAdapter Using a Simplified Main Query

Bu öğreticide, NorthwindWithSprocs veri kümesindeki Employees tablo için bir TableAdapter ve kesin olarak yazılmış bir DataTable ekleyeceğiz.For this tutorial we will add a TableAdapter and strongly-typed DataTable for the Employees table in the NorthwindWithSprocs DataSet. Employees tablosu, çalışan s Manager 'ın EmployeeID belirtilen bir ReportsTo alanı içerir.The Employees table contains a ReportsTo field that specified the EmployeeID of the employee s manager. Örneğin, çalışan Anne Dodsworth 'un, Steven Uludağ 'ın EmployeeID ReportTo değeri 5 ' tir.For example, employee Anne Dodsworth has a ReportTo value of 5, which is the EmployeeID of Steven Buchanan. Sonuç olarak, Anne, Steven ve yöneticisini raporlar.Consequently, Anne reports to Steven, her manager. Her çalışan ReportsTo değerini raporlamaya birlikte, yönetici adlarını da almak da isteyebilirsiniz.Along with reporting each employee s ReportsTo value, we might also want to retrieve the name of their manager. Bu, bir JOINkullanılarak gerçekleştirilebilir.This can be accomplished using a JOIN. Ancak, ilk olarak TableAdapter oluştururken bir JOIN kullanmak, sihirbazın ilgili ekleme, güncelleştirme ve silme yeteneklerini otomatik olarak oluşturmasını da ister.But using a JOIN when initially creating the TableAdapter precludes the wizard from automatically generating the corresponding insert, update, and delete capabilities. Bu nedenle, ana sorgusu hiç JOIN s içermeyen bir TableAdapter oluşturarak başlayacağız.Therefore, we will start by creating a TableAdapter whose main query does not contain any JOIN s. Ardından, adım 2 ' de, yönetici adını bir JOINaracılığıyla almak için ana sorgu saklı yordamını güncelleştireceğiz.Then, in Step 2, we will update the main query stored procedure to retrieve the manager s name via a JOIN.

~/App_Code/DAL klasöründe NorthwindWithSprocs veri kümesini açarak başlayın.Start by opening the NorthwindWithSprocs DataSet in the ~/App_Code/DAL folder. Tasarımcıya sağ tıklayın, bağlam menüsünden Ekle seçeneğini belirleyin ve TableAdapter menü öğesini seçin.Right-click on the Designer, select the Add option from the context menu, and pick the TableAdapter menu item. Bu, TableAdapter Yapılandırma Sihirbazı 'nı başlatır.This will launch the TableAdapter Configuration wizard. Şekil 5 ' te gösterildiği gibi, sihirbazın yeni saklı yordamlar oluşturmasını ve Ileri ' ye tıkladığını gösterir.As Figure 5 depicts, have the wizard create new stored procedures and click Next. TableAdapter s sihirbazından yeni saklı yordamlar oluşturmaya yönelik Yenileyici için, yazılan veri kümesi s TableAdapters öğreticisi Için yeni saklı yordamlar oluşturma bölümüne bakın.For a refresher on creating new stored procedures from the TableAdapter s wizard, consult the Creating New Stored Procedures for the Typed DataSet s TableAdapters tutorial.

yeni saklı yordamlar oluştur seçeneğini belirleyinSelect the Create new stored procedures Option

Şekil 5: Yeni saklı yordamlar oluştur seçeneğini belirleyin (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 5: Select the Create new stored procedures Option (Click to view full-size image)

TableAdapter s ana sorgusu için aşağıdaki SELECT ifadesini kullanın:Use the following SELECT statement for the TableAdapter s main query:

SELECT EmployeeID, LastName, FirstName, Title, HireDate, ReportsTo, Country
FROM Employees

Bu sorgu hiçbir JOIN s içermediğinden, TableAdapter Sihirbazı ilgili INSERT, UPDATEve DELETE deyimleriyle otomatik olarak saklı yordamlar oluşturacak ve ana sorguyu yürütmek için bir saklı yordam oluşturacaktır.Since this query does not include any JOIN s, the TableAdapter wizard will automatically create stored procedures with corresponding INSERT, UPDATE, and DELETE statements, as well as a stored procedure for executing the main query.

Aşağıdaki adım, TableAdapter saklı yordamlarını ad etmemizi sağlar.The following step allows us to name the TableAdapter s stored procedures. Şekil 6 ' da gösterildiği gibi Employees_Select, Employees_Insert, Employees_Updateve Employees_Deleteadlarını kullanın.Use the names Employees_Select, Employees_Insert, Employees_Update, and Employees_Delete, as shown in Figure 6.

TableAdapter saklı yordamlarını adlandırınName the TableAdapter s Stored Procedures

Şekil 6: TableAdapter s saklı yordamlarını adlandırın (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 6: Name the TableAdapter s Stored Procedures (Click to view full-size image)

Son adım, TableAdapter s yöntemlerini adı etmemizi ister.The final step prompts us to name the TableAdapter s methods. Yöntem adları olarak Fill ve GetEmployees kullanın.Use Fill and GetEmployees as the method names. Ayrıca, güncelleştirmeleri doğrudan veritabanına göndermek için oluşturma yöntemlerini de bırakın (GenerateDBDirectMethods) onay kutusunun işaretli olduğundan emin olun.Also be sure to leave the Create methods to send updates directly to the database (GenerateDBDirectMethods) checkbox checked.

TableAdapter s yöntemlerinin Fill ve GetEmployees adına adıName the TableAdapter s Methods Fill and GetEmployees

Şekil 7: TableAdapter s metotlarını Fill ve GetEmployees adlandırın (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 7: Name the TableAdapter s Methods Fill and GetEmployees (Click to view full-size image)

Sihirbazı tamamladıktan sonra, veritabanında saklı yordamları incelemek için bir dakikanızı ayırın.After completing the wizard, take a moment to examine the stored procedures in the database. Dört yeni tane görmeniz gerekir: Employees_Select, Employees_Insert, Employees_Updateve Employees_Delete.You should see four new ones: Employees_Select, Employees_Insert, Employees_Update, and Employees_Delete. Sonra, EmployeesDataTable ve yeni oluşturulan EmployeesTableAdapter inceleyin.Next, inspect the EmployeesDataTable and EmployeesTableAdapter just created. DataTable, ana sorgu tarafından döndürülen her alan için bir sütun içerir.The DataTable contains a column for each field returned by the main query. TableAdapter ' a tıklayın ve ardından Özellikler penceresi gidin.Click on the TableAdapter and then go to the Properties window. InsertCommand, UpdateCommandve DeleteCommand özelliklerinin ilgili saklı yordamları çağırmak üzere doğru şekilde yapılandırıldığını görürsünüz.There you will see that the InsertCommand, UpdateCommand, and DeleteCommand properties are correctly configured to call the corresponding stored procedures.

TableAdapter INSERT, Update ve DELETE özelliklerini IçerirThe TableAdapter Includes Insert, Update, and Delete Capabilities

Şekil 8: TableAdapter INSERT, Update ve DELETE özelliklerini içerir (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 8: The TableAdapter Includes Insert, Update, and Delete Capabilities (Click to view full-size image)

Ekleme, güncelleştirme ve silme saklı yordamları otomatik olarak oluşturulur ve InsertCommand, UpdateCommandve DeleteCommand özellikleri doğru şekilde yapılandırıldıysa, her çalışan Yöneticisi hakkında ek bilgi döndürmek için SelectCommand s saklı yordamını özelleştirmeye hazırız.With the insert, update, and delete stored procedures automatically created and the InsertCommand, UpdateCommand, and DeleteCommand properties correctly configured, we are ready to customize the SelectCommand s stored procedure to return additional information about each employee s manager. Özellikle, bir JOIN kullanmak ve Manager s FirstName ve LastName değerlerini döndürmek için Employees_Select saklı yordamını güncelleştirmemiz gerekir.Specifically, we need to update the Employees_Select stored procedure to use a JOIN and return the manager s FirstName and LastName values. Saklı yordam güncelleştirildikten sonra DataTable 'ı bu ek sütunları içerecek şekilde güncelleştirmemiz gerekir.After the stored procedure has been updated, we will need to update the DataTable so that it includes these additional columns. 2 ve 3. adımlarda bu iki görevi ele alacağız.We'll tackle these two tasks in Steps 2 and 3.

2. Adım: saklı yordamı birJOIN Içerecek şekilde özelleştirmeStep 2: Customizing the Stored Procedure to Include aJOIN

Sunucu Gezgini giderek başlayın, Northwind veritabanı s saklı yordamları klasörünün detayına gidin ve Employees_Select saklı yordamını açın.Start by going to the Server Explorer, drilling down into the Northwind database s Stored Procedures folder, and opening the Employees_Select stored procedure. Bu saklı yordamı görmüyorsanız, saklı yordamlar klasörüne sağ tıklayın ve Yenile ' yi seçin.If you do not see this stored procedure, right-click on the Stored Procedures folder and choose Refresh. Saklı yordamı, yöneticinin ilk ve son adını döndürmek için bir LEFT JOIN kullanacak şekilde güncelleştirin:Update the stored procedure so that it uses a LEFT JOIN to return the manager s first and last name:

SELECT Employees.EmployeeID, Employees.LastName, 
       Employees.FirstName, Employees.Title, 
       Employees.HireDate, Employees.ReportsTo, 
       Employees.Country,
       Manager.FirstName as ManagerFirstName, 
       Manager.LastName as ManagerLastName
FROM Employees
    LEFT JOIN Employees AS Manager ON
        Employees.ReportsTo = Manager.EmployeeID

SELECT ifadesini güncelleştirdikten sonra, Dosya menüsüne gidip kaydet Employees_Select' i seçerek değişiklikleri kaydedin.After updating the SELECT statement, save the changes by going to the File menu and choosing Save Employees_Select. Alternatif olarak, araç çubuğundaki Kaydet simgesine tıklayabilir veya CTRL + S ' ye basabilirsiniz.Alternatively, you can click the Save icon in the toolbar or hit Ctrl+S. Değişikliklerinizi kaydettikten sonra, Sunucu Gezgini Employees_Select saklı yordamına sağ tıklayın ve Yürüt ' ü seçin.After saving your changes, right-click on the Employees_Select stored procedure in the Server Explorer and choose Execute. Bu işlem, saklı yordamı çalıştırır ve sonuçlarını çıkış penceresinde gösterir (bkz. Şekil 9).This will run the stored procedure and show its results in the Output window (see Figure 9).

saklı yordam sonuçları Çıkış Penceresi görüntülenirThe Stored Procedures Results are Displayed in the Output Window

Şekil 9: saklı yordam sonuçları çıkış penceresi görüntülenir (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 9: The Stored Procedures Results are Displayed in the Output Window (Click to view full-size image)

3. Adım: DataTable s sütunlarını güncelleştirmeStep 3: Updating the DataTable s Columns

Bu noktada, Employees_Select saklı yordamı ManagerFirstName ve ManagerLastName değerler döndürür, ancak EmployeesDataTable bu sütunlar eksik.At this point, the Employees_Select stored procedure returns ManagerFirstName and ManagerLastName values, but the EmployeesDataTable is missing these columns. Bu eksik sütunlar DataTable 'a iki şekilde eklenebilir:These missing columns can be added to the DataTable in one of two ways:

  • Veri kümesi tasarımcısında DataTable üzerinde el ile sağ tıklayın ve Ekle menüsünde sütun ' u seçin.Manually - right-click on the DataTable in the DataSet Designer and, from the Add menu, choose Column. Daha sonra sütunu verebilir ve özelliklerini uygun şekilde ayarlayabilirsiniz.You can then name the column and set its properties accordingly.
  • Otomatik olarak -TableAdapter Yapılandırma Sihirbazı, DataTable s sütunlarını SelectCommand saklı yordamının döndürdüğü alanları yansıtacak şekilde güncelleştirir.Automatically - the TableAdapter Configuration wizard will update the DataTable s columns to reflect the fields returned by the SelectCommand stored procedure. Geçici SQL deyimlerini kullanırken, SelectCommand artık bir JOINiçerdiğinden, sihirbaz InsertCommand, UpdateCommandve DeleteCommand özelliklerini de kaldırır.When using ad-hoc SQL statements, the wizard will also remove the InsertCommand, UpdateCommand, and DeleteCommand properties since the SelectCommand now contains a JOIN. Ancak saklı yordamlar kullanılırken bu komut özellikleri değişmeden kalır.But when using stored procedures, these command properties remain intact.

Bir ayrıntılar DataList ve dosya karşıya yükleme Içeren bir ana kayıt listesi listesini kullanarak ana/ayrıntı dahil olmak üzere önceki öğreticilere DataTable sütunlarını el ile eklemeyi araştırdık. bu işleme sonraki öğreticimizde daha ayrıntılı bir şekilde bakacağız.We have explored manually adding DataTable columns in previous tutorials, including Master/Detail Using a Bulleted List of Master Records with a Details DataList and Uploading Files, and we will look at this process again in more detail in our next tutorial. Bununla birlikte, bu öğretici için TableAdapter Yapılandırma Sihirbazı aracılığıyla otomatik yaklaşımı kullanalım.For this tutorial, however, let s use the automatic approach via the TableAdapter Configuration wizard.

EmployeesTableAdapter sağ tıklayıp bağlam menüsünden Yapılandır ' ı seçerek başlayın.Start by right-clicking on the EmployeesTableAdapter and selecting Configure from the context menu. Bu, seçme, ekleme, güncelleştirme ve silme için kullanılan saklı yordamları, dönüş değerleri ve parametreleriyle birlikte (varsa) listeleyen TableAdapter Yapılandırma Sihirbazı 'nı getirir.This brings up the TableAdapter Configuration wizard, which lists the stored procedures used for selecting, inserting, updating, and deleting, along with their return values and parameters (if any). Şekil 10 Bu Sihirbazı gösterir.Figure 10 shows this wizard. Burada Employees_Select saklı yordamının artık ManagerFirstName ve ManagerLastName alanlarını döndürdüğünü görebiliriz.Here we can see that the Employees_Select stored procedure now returns the ManagerFirstName and ManagerLastName fields.

sihirbaz Employees_Select saklı yordamının güncelleştirilmiş sütun listesini gösterirThe Wizard Shows the Updated Column List for the Employees_Select Stored Procedure

Şekil 10: sihirbaz Employees_Select saklı yordamının güncelleştirilmiş sütun listesini gösterir (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 10: The Wizard Shows the Updated Column List for the Employees_Select Stored Procedure (Click to view full-size image)

Son ' a tıklayarak Sihirbazı doldurun.Complete the wizard by clicking Finish. Veri kümesi tasarımcısına dönmesinden sonra, EmployeesDataTable iki ek sütun içerir: ManagerFirstName ve ManagerLastName.Upon returning to the DataSet Designer, the EmployeesDataTable includes two additional columns: ManagerFirstName and ManagerLastName.

EmployeesDataTable Iki yeni sütun IçerirThe EmployeesDataTable Contains Two New Columns

Şekil 11: EmployeesDataTable Iki yeni sütun içerir (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 11: The EmployeesDataTable Contains Two New Columns (Click to view full-size image)

Güncelleştirilmiş Employees_Select saklı yordamının geçerli olduğunu ve TableAdapter 'ın INSERT, Update ve DELETE özelliklerini hala işlevsel olduğunu anlamak için, kullanıcıların çalışanları görüntülemesine ve silmesine izin veren bir Web sayfası oluşturmasına izin verin.To illustrate that the updated Employees_Select stored procedure is in effect and that the insert, update, and delete capabilities of the TableAdapter are still functional, let s create a web page that allows users to view and delete employees. Bununla birlikte, böyle bir sayfa oluşturmadan önce, NorthwindWithSprocs veri kümesindeki çalışanlarla çalışmak üzere Iş mantığı katmanında yeni bir sınıf oluşturmanız gerekir.Before we create such a page, however, we need to first create a new class in the Business Logic Layer for working with employees from the NorthwindWithSprocs DataSet. 4. adımda bir EmployeesBLLWithSprocs sınıfı oluşturacağız.In Step 4, we will create an EmployeesBLLWithSprocs class. 5. adımda bu sınıfı bir ASP.NET sayfasından kullanacağız.In Step 5, we will use this class from an ASP.NET page.

4. Adım: Iş mantığı katmanını uygulamaStep 4: Implementing the Business Logic Layer

EmployeesBLLWithSprocs.csadlı ~/App_Code/BLL klasörde yeni bir sınıf dosyası oluşturun.Create a new class file in the ~/App_Code/BLL folder named EmployeesBLLWithSprocs.cs. Bu sınıf, var olan EmployeesBLL sınıfının semantiğini taklit eder, yalnızca bu yeni bir tane daha az yöntem sağlar ve NorthwindWithSprocs veri kümesini kullanır (Northwind veri kümesi yerine).This class mimics the semantics of the existing EmployeesBLL class, only this new one provides fewer methods and uses the NorthwindWithSprocs DataSet (instead of the Northwind DataSet). Aşağıdaki kodu EmployeesBLLWithSprocs sınıfına ekleyin.Add the following code to the EmployeesBLLWithSprocs class.

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 NorthwindWithSprocsTableAdapters;
[System.ComponentModel.DataObject]
public class EmployeesBLLWithSprocs
{
    private EmployeesTableAdapter _employeesAdapter = null;
    protected EmployeesTableAdapter Adapter
    {
        get
        {
            if (_employeesAdapter == null)
                _employeesAdapter = new EmployeesTableAdapter();
            return _employeesAdapter;
        }
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Select, true)]
    public NorthwindWithSprocs.EmployeesDataTable GetEmployees()
    {
        return Adapter.GetEmployees();
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Delete, true)]
    public bool DeleteEmployee(int employeeID)
    {
        int rowsAffected = Adapter.Delete(employeeID);
        // Return true if precisely one row was deleted, otherwise false
        return rowsAffected == 1;
    }
}

EmployeesBLLWithSprocs sınıf s Adapter özelliği NorthwindWithSprocs veri EmployeesTableAdapterkümesinin bir örneğini döndürür.The EmployeesBLLWithSprocs class s Adapter property returns an instance of the NorthwindWithSprocs DataSet s EmployeesTableAdapter. Bu, sınıf s GetEmployees ve DeleteEmployee yöntemleri tarafından kullanılır.This is used by the class s GetEmployees and DeleteEmployee methods. GetEmployees yöntemi, Employees_Select saklı yordamını çağıran ve sonuçlarını bir EmployeeDataTabledolduran EmployeesTableAdapter s karşılık gelen GetEmployees yöntemini çağırır.The GetEmployees method calls the EmployeesTableAdapter s corresponding GetEmployees method, which invokes the Employees_Select stored procedure and populates its results in an EmployeeDataTable. DeleteEmployee yöntemi benzer şekilde Employees_Delete saklı yordamını çağıran EmployeesTableAdapter s Delete yöntemini çağırır.The DeleteEmployee method similarly calls the EmployeesTableAdapter s Delete method, which invokes the Employees_Delete stored procedure.

5. Adım: sunu katmanındaki verilerle çalışmaStep 5: Working with the Data in the Presentation Layer

EmployeesBLLWithSprocs sınıfı tamamlandıktan sonra, ASP.NET sayfası aracılığıyla çalışan verileriyle çalışmaya hazırız.With the EmployeesBLLWithSprocs class complete, we re ready to work with employee data through an ASP.NET page. AdvancedDAL klasöründeki JOINs.aspx sayfasını açın ve araç kutusu 'ndaki bir GridView 'u ID özelliğini Employeesolarak ayarlayarak tasarımcı üzerine sürükleyin.Open the JOINs.aspx page in the AdvancedDAL folder and drag a GridView from the Toolbox onto the Designer, setting its ID property to Employees. Ardından, GridView s akıllı etiketinden, Kılavuzu EmployeesDataSourceadlı yeni bir ObjectDataSource denetimine bağlayın.Next, from the GridView s smart tag, bind the grid to a new ObjectDataSource control named EmployeesDataSource.

ObjectDataSource 'u EmployeesBLLWithSprocs sınıfını kullanacak şekilde yapılandırın ve SEÇIM ve SILME sekmelerinden, GetEmployees ve DeleteEmployee yöntemlerinin açılan listelerden seçildiğinden emin olun.Configure the ObjectDataSource to use the EmployeesBLLWithSprocs class and, from the SELECT and DELETE tabs, ensure that the GetEmployees and DeleteEmployee methods are selected from the drop-down lists. ObjectDataSource 'un yapılandırmasını gerçekleştirmek için son ' a tıklayın.Click Finish to complete the ObjectDataSource s configuration.

, bir EmployeesBLLWithSprocs sınıfını kullanacak şekilde yapılandırmaConfigure the ObjectDataSource to Use the EmployeesBLLWithSprocs Class

Şekil 12: EmployeesBLLWithSprocs sınıfını kullanmak için ObjectDataSource 'ı yapılandırma (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 12: Configure the ObjectDataSource to Use the EmployeesBLLWithSprocs Class (Click to view full-size image)

ObjectDataSource, GetEmployees ve DeleteEmployee yöntemlerini kullanırHave the ObjectDataSource Use the GetEmployees and DeleteEmployee Methods

Şekil 13: ObjectDataSource 'un GetEmployees ve DeleteEmployee yöntemlerini kullanmasınısağlar (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 13: Have the ObjectDataSource Use the GetEmployees and DeleteEmployee Methods (Click to view full-size image)

Visual Studio, EmployeesDataTable s sütunlarının her biri için GridView 'a bir BoundField ekler.Visual Studio will add a BoundField to the GridView for each of the EmployeesDataTable s columns. Title, LastName, FirstName, ManagerFirstNameve ManagerLastName dışındaki tüm bu BoundFields alanlarını kaldırın ve son dört BoundFields HeaderText özelliklerini sırasıyla soyadı, Ilk adı, yönetici adı ve yönetici soyadı olarak yeniden adlandırın.Remove all of these BoundFields except for Title, LastName, FirstName, ManagerFirstName, and ManagerLastName and rename the HeaderText properties for the last four BoundFields to Last Name, First Name, Manager s First Name, and Manager s Last Name, respectively.

Kullanıcıların bu sayfadan çalışanları silmesine izin vermek için iki şey yapmanız gerekir.To allow users to delete employees from this page we need to do two things. İlk olarak, GridView 'a akıllı etiketinden silmeyi etkinleştir seçeneğini işaretleyerek, silme özelliği sağlamayı söyleyin.First, instruct the GridView to provide deleting capabilities by checking the Enable Deleting option from its smart tag. İkincisi, ObjectDataSource 'un OldValuesParameterFormatString özelliğini, ObjectDataSource Sihirbazı (original_{0}) tarafından ayarlanan değerden varsayılan değer ({0}) olarak değiştirin.Second, change the ObjectDataSource s OldValuesParameterFormatString property from the value set by the ObjectDataSource wizard (original_{0}) to its default value ({0}). Bu değişiklikleri yaptıktan sonra, GridView ve ObjectDataSource 'un bildirim temelli biçimlendirmesi aşağıdakine benzer görünmelidir:After making these changes, your GridView and ObjectDataSource s declarative markup should look similar to the following:

<asp:GridView ID="Employees" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="EmployeeID" DataSourceID="EmployeesDataSource">
    <Columns>
        <asp:CommandField ShowDeleteButton="True" />
        <asp:BoundField DataField="Title" 
            HeaderText="Title" 
            SortExpression="Title" />
        <asp:BoundField DataField="LastName" 
            HeaderText="Last Name" 
            SortExpression="LastName" />
        <asp:BoundField DataField="FirstName" 
            HeaderText="First Name" 
            SortExpression="FirstName" />
        <asp:BoundField DataField="ManagerFirstName" 
            HeaderText="Manager's First Name" 
            SortExpression="ManagerFirstName" />
        <asp:BoundField DataField="ManagerLastName" 
            HeaderText="Manager's Last Name" 
            SortExpression="ManagerLastName" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="EmployeesDataSource" runat="server" 
    DeleteMethod="DeleteEmployee" OldValuesParameterFormatString="{0}" 
    SelectMethod="GetEmployees" TypeName="EmployeesBLLWithSprocs">
    <DeleteParameters>
        <asp:Parameter Name="employeeID" Type="Int32" />
    </DeleteParameters>
</asp:ObjectDataSource>

Sayfayı bir tarayıcı aracılığıyla ziyaret ederek test edin.Test out the page by visiting it through a browser. Şekil 14 ' te gösterildiği gibi, sayfada her bir çalışan ve onun yönetici adı (bir tane olduğu varsayılarak) listelenir.As Figure 14 shows, the page will list each employee and his or her manager s name (assuming they have one).

Employees_Select saklı yordamında KATıLMAYı , yöneticinin adını döndürürThe JOIN in the Employees_Select Stored Procedure Returns the Manager s Name

Şekil 14: Employees_Select saklı yordamındaki JOIN, yönetici adını (tam boyutlu görüntüyü görüntülemek Için tıklayın) döndürürFigure 14: The JOIN in the Employees_Select Stored Procedure Returns the Manager s Name (Click to view full-size image)

Sil düğmesine tıklamak, Employees_Delete saklı yordamının yürütülmesinde yürütülen iş akışını silme işlemini başlatır.Clicking the Delete button starts the deleting workflow, which culminates in the execution of the Employees_Delete stored procedure. Ancak, bir yabancı anahtar kısıtlaması ihlali nedeniyle saklı yordamdaki denenen DELETE deyimleri başarısız olur (bkz. Şekil 15).However, the attempted DELETE statement in the stored procedure fails because of a foreign key constraint violation (see Figure 15). Özellikle, her çalışanın Orders tablodaki bir veya daha fazla kaydı vardır ve bu da silmenin başarısız olmasına neden olur.Specifically, each employee has one or more records in the Orders table, causing the delete to fail.

Karşılık gelen siparişlerin bulunduğu bir çalışanın silinmesi yabancı anahtar kısıtlaması Ihlaline neden olurDeleting an Employee That has Corresponding Orders Results in a Foreign Key Constraint Violation

Şekil 15: karşılık gelen siparişleri olan bir çalışanın silinmesi yabancı anahtar kısıtlaması ihlaline neden olur (tam boyutlu görüntüyü görüntülemek için tıklayın)Figure 15: Deleting an Employee That has Corresponding Orders Results in a Foreign Key Constraint Violation (Click to view full-size image)

Bir çalışanın silinmesine izin vermek için şunları yapabilirsiniz:To allow an employee to be deleted you could:

Bunu okuyucu için bir alıştırma olarak bırakıyorum.I leave this as an exercise for the reader.

ÖzetSummary

İlişkisel veritabanları ile çalışırken, sorguların verileri birden çok, ilişkili tablodan çekmesini yaygındır.When working with relational databases, it is common for queries to pull their data from multiple, related tables. Bağıntılı alt sorgular ve JOIN s bir sorgudaki ilgili tablolardan verilere erişmek için iki farklı teknik sağlar.Correlated subqueries and JOIN s provide two different techniques for accessing data from related tables in a query. Önceki öğreticilerde, TableAdapter JOIN s içeren sorgular için INSERT, UPDATEve DELETE deyimlerini otomatik olarak üretireceğiz için bağıntılı alt sorguları en yaygın olarak kullandık.In previous tutorials we most commonly made use of correlated subqueries because the TableAdapter cannot auto-generate INSERT, UPDATE, and DELETE statements for queries involving JOIN s. Bu değerler el ile sağlanırken, TableAdapter Yapılandırma Sihirbazı tamamlandığında, geçici SQL deyimleri kullanılırken tüm özelleştirmeler üzerine yazılır.While these values can be provided manually, when using ad-hoc SQL statements any customizations will be overwritten when the TableAdapter Configuration wizard is completed.

Neyse ki, saklı yordamlar kullanılarak oluşturulan TableAdapters, ad-hoc SQL deyimleriyle oluşturulan aynı briı ile karşılaşmaz.Fortunately, TableAdapters created using stored procedures do not suffer from the same brittleness as those created using ad-hoc SQL statements. Bu nedenle, ana sorgusu saklı yordamları kullanırken JOIN kullanan bir TableAdapter oluşturmak uygulanabilir.Therefore, it is feasible to create a TableAdapter whose main query uses a JOIN when using stored procedures. Bu öğreticide, böyle bir TableAdapter oluşturmayı nasıl oluşturacağınız gördük.In this tutorial we saw how to create such a TableAdapter. İlişkili ekleme, güncelleştirme ve silme saklı yordamlarının otomatik olarak oluşturulması için TableAdapter s ana sorgusu için JOINseyrek SELECT bir sorgu kullanarak başladık.We started by using a JOIN-less SELECT query for the TableAdapter s main query so that the corresponding insert, update, and delete stored procedures would be auto-created. TableAdapter 'ın ilk yapılandırması tamamlandıktan sonra, bir JOIN kullanmak ve EmployeesDataTable s sütunlarını güncelleştirmek için TableAdapter Yapılandırma Sihirbazı 'nı yeniden çalıştırdık SelectCommand saklı yordamını genişlettik.With the TableAdapter s initial configuration complete, we augmented the SelectCommand stored procedure to use a JOIN and re-ran the TableAdapter Configuration wizard to update the EmployeesDataTable s columns.

TableAdapter Yapılandırma Sihirbazı 'nı yeniden çalıştırmak, EmployeesDataTable sütunlarını Employees_Select saklı yordamının döndürdüğü veri alanlarını yansıtacak şekilde otomatik olarak güncelleştirirler.Re-running the TableAdapter Configuration wizard automatically updated the EmployeesDataTable columns to reflect the data fields returned by the Employees_Select stored procedure. Alternatif olarak, bu sütunları DataTable 'a el ile de ekledik.Alternatively, we could have added these columns manually to the DataTable. Sonraki öğreticide DataTable 'a el ile sütun ekleme hakkında araştıracağız.We will explore manually adding columns to the DataTable in the next tutorial.

Programlamanın kutlu olsun!Happy Programming!

Yazar hakkındaAbout the Author

4GuysFromRolla.com 'in, Scott Mitchell, yedi ASP/ASP. net books ve 'in yazarı, 1998 sürümünden bu yana Microsoft Web teknolojileriyle çalışmaktadır.Scott Mitchell, author of seven ASP/ASP.NET books and founder of 4GuysFromRolla.com, has been working with Microsoft Web technologies since 1998. Scott bağımsız danışman, Trainer ve yazıcı olarak çalışıyor.Scott works as an independent consultant, trainer, and writer. En son kitabı, 24 saat içinde ASP.NET 2,0 kendi kendinize eğitimister.His latest book is Sams Teach Yourself ASP.NET 2.0 in 24 Hours. mitchell@4GuysFromRolla.comadresinden erişilebilir .He can be reached at mitchell@4GuysFromRolla.com. ya da blog aracılığıyla http://ScottOnWriting.NETbulabilirsiniz.or via his blog, which can be found at http://ScottOnWriting.NET.

Özel olarak teşekkürlerSpecial Thanks To

Bu öğretici serisi birçok yararlı gözden geçirenler tarafından incelendi.This tutorial series was reviewed by many helpful reviewers. Bu öğreticide lider gözden geçirenler, Kiton Geisenow, David suru ve TeReSaN Murphy.Lead reviewers for this tutorial were Hilton Geisenow, David Suru, and Teresa Murphy. Yaklaşan MSDN makalelerimi gözden geçiriyor musunuz?Interested in reviewing my upcoming MSDN articles? Öyleyse, benimitchell@4GuysFromRolla.combir satır bırakın .If so, drop me a line at mitchell@4GuysFromRolla.com.