Makale numarası: 320301 - Son Gözden Geçirme: 01 Şubat 2004 Pazar - Gözden geçirme: 3.4

NASıL YAPıLıR: Visual C# .NET Web kullanarak bir Windows Forms uygulaması bir kimlik sütun ile üst ve alt veri güncelleştirme hizmeti

Sistem İpucuBu makale, kullandığınızdan farklı bir işletim sistemine yöneliktir. Sizinle ilgili olmayabilecek makale içeriği devre dışı bırakıldı.

Bu Sayfada

Hepsini aç | Hepsini kapa

Özet

Bu adım adım makalede, bir Web hizmetinden bir DataSet nesnesi almak nasıl, nasıl yapılır: DiffGram güncelleştirmeler Web hizmetine gönderebilirsiniz ve alt düzey geri istemci DataSet güncelleştirilmiş DiffGram nasıl açıklar. Bu işlem, aşağıdaki adımları içerir:
  1. Istemci uygulaması, Web hizmetinden bir DataSet nesnesi bir üst-altöge ilişkisi içindeki iki DataTable nesnelerle alır. Üst DataTable, birincil anahtar olarak bir kimlik/otomatik numara sütunu içermiyor.
  2. Istemci uygulamasında kullanıcı ekleyebilir, silme ve alt kayıt üst kayıt değiştirin. Yeni üst kayıt yerel olarak oluşturulan geçici bir birincil anahtar değerini alırsınız.
  3. Istemci uygulaması, değişiklikleri geri Web'e gönderir bir DiffGram olarak hizmet.
  4. Web hizmeti veritabanını güncelleştirir, yeni üst kayıt gerçek birincil anahtar değerleri alır ve sonra alt kayıtları için değiştirilen anahtar değerleri yayar.
  5. Istemci uygulaması Web hizmetinden güncelleştirilmiş değerleri alır ve sonra da güncelleştirilen değerler geri yerel DataSet içinde birleştirir.
Bir Web hizmetini kullanarak, tek bir tabloyu güncelleştirme hakkında ek bilgi için Microsoft Knowledge Base'deki makaleyi görüntülemek üzere aşağıdaki makale numarasını tıklatın:
310143  (http://support.microsoft.com/kb/310143/EN-US/ ) NASıL YAPıLıR: ADO.NET ve Visual C# .NET kullanarak Web üzerinden Server veri güncelleştirme hizmeti.

Gereksinimler

Aşağıdaki listede, gereksinim duyulan donanım, yazılım, ağ altyapısı ve hizmet paketleri önerilmektedir:
  • Microsoft Windows 2000 Professional, Windows 2000 Server, Windows Server veya Windows NT 4.0 Server 2000 Advanced
  • Microsoft Visual Studio. NET'i
Bu makalede, aşağıdaki konularda bilgi sahibi olduğunuz varsayılmaktadır:
  • Visual Studio .NET
  • ADO.NET temelleri ve sözdizimi
  • ASP.NET temelleri ve sözdizimi
Bu makaledeki kod örnekleri, Web sunucusu http://localhost kullanır. Ayrıca, kod örnekleri, veritabanı olarak Northwind veritabanını kullanır. Northwind veritabanını, Microsoft SQL Server ile birlikte bulunur.

Web hizmetini oluşturma

  1. Yeni bir Visual C# ASP.NET Web hizmeti projesi oluşturmak için aşağıdaki adımları izleyin:
    1. Visual Studio .NET'i başlatın.
    2. Dosya menüsünde Yeni ' nin üzerine gelin ve sonra Project ' i tıklatın.
    3. Project Types altında Visual C# Projects ' ı tıklatın ve sonra şablonları altında ASP.NET Web Service ' ı tıklatın.
    4. Varsayılan konum, Konum kutusuna http://localhost/WebService1 görünür. (Örneğin, http://localhost çalışır yerel sunucunuz üzerinde Web hizmeti) sunucunuzun URL'SINI yazın. Replace WebService1 CSharpUpdateData ile. URL <a0>Konum</a0> kutusunda, aşağıdaki gibi görünmelidir:
      http://localhost/CSharpUpdateData
    5. <a0>New Project</a0> iletişim kutusunu kapatmak için Tamam ' ı tıklatın.
  2. Service1.asmx.cs[Design üzerinde] sayfasında, kod görünümüne geçin. Web hizmeti için kod penceresine görüntülendiğine dikkat edin.
  3. <a0>Kod</a0> penceresinin en üstünde kullanarak aşağıdaki deyimi ekleyin:
    using System.Data.SqlClient;
  4. <a1>Sınıf</a1> Service1 uygulamasına aşağıdakileri ekleyin:
            [WebMethod]
            public DataSet GetData()
            {
                SqlConnection conn = new SqlConnection ("server=vcdb02;uid=sa;pwd=ricka;database=northwind");
                //Pull back the recent orders for the parent rows.
                SqlDataAdapter daOrder = new SqlDataAdapter("SELECT * FROM Orders WHERE OrderDate >= '05/01/1998'",conn);
                //Get only the appropriate child rows for the parent rows.
                SqlDataAdapter daDetails = new SqlDataAdapter("SELECT * FROM [Order Details] WHERE OrderID in ( SELECT OrderID FROM Orders WHERE OrderDate >= '05/01/1998')",conn);
    
                DataSet ds = new DataSet();
                try
                {
    				
                    //Fill DataSet, and then set DataRelation to move through the DataGrid.
                    conn.Open();
    
                    daOrder.FillSchema(ds,SchemaType.Mapped,"Orders");
                    daOrder.Fill(ds,"Orders");
    
                    daDetails.FillSchema(ds,SchemaType.Mapped,"Details");
                    daDetails.Fill(ds,"Details");
    
                    ds.Relations.Add("OrdDetail", ds.Tables["Orders"].Columns["OrderID"], ds.Tables["Details"].Columns["OrderID"]);
    			
                    DataColumn dc = ds.Tables["Orders"].Columns["OrderID"];
                    dc.AutoIncrement = true;
                    dc.AutoIncrementSeed = -1;
                    dc.AutoIncrementStep = -1;
                }
                catch(SqlException ex)
                {
                    Console.Write (ex.Message.ToString ());
                    Console.Write(ex.InnerException.ToString ());
    
                }
    
                return ds;
            }
    		
            [WebMethod]
            public DataSet UpdateData(DataSet ds)
            {
                SqlConnection conn = new SqlConnection ("server=vcdb02;uid=sa;pwd=ricka;database=northwind");
                //Pull back the recent orders for the parent rows.
                SqlDataAdapter daOrders = new SqlDataAdapter("SELECT * FROM Orders WHERE OrderDate >= '05/01/1998'",conn);
                //Get only the appropriate child rows for the parent rows.
                SqlDataAdapter daDetails = new SqlDataAdapter("SELECT * FROM [Order Details] WHERE OrderID in ( SELECT OrderID FROM Orders WHERE OrderDate >= '05/01/1998')",conn);
    
    			
                try
                {
                    conn.Open();
                    // Get commands for the Orders table.
                    // Reselect record after insert to get new Identity value.
                    // You must get the schema, which you did in GetData(), before you get commands; 
                    // otherwise, the Command builder tries to insert new rows, based 
                    // on the Identity column.
                    SqlCommandBuilder cb = new SqlCommandBuilder(daOrders);
                    daOrders.DeleteCommand = cb.GetDeleteCommand();
                    daOrders.UpdateCommand = cb.GetUpdateCommand();
                    daOrders.InsertCommand = cb.GetInsertCommand();
                    daOrders.InsertCommand.CommandText = String.Concat(daOrders.InsertCommand.CommandText, "; Select * From Orders Where OrderID = @@IDENTITY");
    
                    //UpdateRowSource tells the DataAdapter that there will be a re-selected record.
          
                    daOrders.InsertCommand.UpdatedRowSource = UpdateRowSource.FirstReturnedRecord;
                    //cb = null;
            
    
                    // Get commands for the Order Details table.
                    // Must set the QuotePrefix and QuoteSuffix; 
                    // otherwise, the CommandBuilder does not put brackets ([])
                    // around the table name.
    
                    SqlCommandBuilder cb1 = new SqlCommandBuilder(daDetails);
                    cb1.QuotePrefix = "[";
                    cb1.QuoteSuffix = "]";
                    daDetails.DeleteCommand = cb1.GetDeleteCommand();
                    daDetails.InsertCommand = cb1.GetInsertCommand();
                    daDetails.UpdateCommand = cb1.GetUpdateCommand();
    
    
                    // Create a new DataAdapter based on the original one to prevent the
                    // CommandBuilder from modifying the SQL statements, 
                    // specifically the custom InsertCommand.
                    // You do not need this if you roll your own commands and parameters 
                    // or if you use the Visual Tools to do it.
               
                    SqlDataAdapter daOrd2 = new SqlDataAdapter();
                    daOrd2.DeleteCommand = daOrders.DeleteCommand;
                    daOrd2.InsertCommand = daOrders.InsertCommand;
                    daOrd2.UpdateCommand = daOrders.UpdateCommand;
    
                    // Use a delegate to prevent AcceptChanges from occurring on Deletes and Inserts.
                    // This is for a limitation of the DataAdapter; see Q313540. 
    
                    daOrd2.RowUpdated += new SqlRowUpdatedEventHandler(OnOrd1RowUpdated);
                    daDetails.RowUpdated += new SqlRowUpdatedEventHandler(OnDetailsRowUpdated);
    
    
                    daDetails.Update(GetDeletedRows(ds.Tables["Details"]));
                    daOrd2.Update(GetDeletedRows(ds.Tables["Orders"]));
                    DataRow [] dsArray = ds.Tables["Orders"].Select("", "", DataViewRowState.ModifiedCurrent);
                    daOrd2.Update(ds.Tables["Orders"].Select("", "", DataViewRowState.ModifiedCurrent));
                    daDetails.Update(ds.Tables["Details"].Select("", "", DataViewRowState.ModifiedCurrent));
    
                    daOrd2.Update(ds.Tables["Orders"].Select("", "", DataViewRowState.Added));
    
                    ds.EnforceConstraints = false;
                    daDetails.Update(ds.Tables["Details"].Select("","", DataViewRowState.Added));
                    ds.EnforceConstraints = true;
    
                    conn.Close();
    
    				
    
                }
                catch(SqlException ex)
                {
                    Console.Write (ex.Message.ToString ());
                    Console.Write(ex.InnerException.ToString ());
                }
                return ds;
            }
    
    
            protected static void OnOrd1RowUpdated(object sender, SqlRowUpdatedEventArgs args)
            {
                if(args.StatementType == StatementType.Insert || args.StatementType == StatementType.Delete )
                    args.Status = UpdateStatus.SkipCurrentRow;
    
            }
            protected static void OnDetailsRowUpdated(object sender, SqlRowUpdatedEventArgs args)
            {
                if(args.StatementType == StatementType.Insert )
                {
                    // Do not allow the AcceptChanges to occur on this row.
                    args.Status = UpdateStatus.SkipCurrentRow;
    
                    // Get the current, actual primary key value so that you can plug it back
                    // in after you get the correct original value that was generated for the child row.
                    int currentkey = (int)args.Row["OrderID"];
                    // This is where you get a correct original value key that is stored to the child row. 
                    // You pull the original, pseudo key value from the parent, plug it in as the child row's primary key
                    // field, and then accept changes on it. Specifically, this is why you turned off EnforceConstraints.
                    args.Row["OrderID"] = args.Row.GetParentRow("OrdDetail")["OrderID",DataRowVersion.Original];
                    args.Row.AcceptChanges();
                    // Store the actual primary key value in the foreign key column of the child row.
                    args.Row["OrderID"] = currentkey;
                }
    
                if(args.StatementType == StatementType.Delete )
                    args.Status = UpdateStatus.SkipCurrentRow;
    
            }
            private DataRow [] GetDeletedRows(DataTable dt)
            {
                DataRow [] dr ;
                if(dt == null)
                    return null;
                dr = dt.Select("","",DataViewRowState.Deleted );
                if(dr.Length ==0 || dr[0] != null)
                    return dr;
                // Workaround:
                // With a remoted DataSet, Select returns the array elements
                // that are filled with Nothing/null instead of DataRow objects.
    					
                for(int i=0; i < (int)dt.Rows.Count; i++)
                {
                    if(dt.Rows[i].RowState ==DataRowState.Deleted )
                        dr[i]=dt.Rows[i];
                }
                return dr;
    						
    
            } 
    					
  5. SQL Server çalıştıran sunucuya bağlanmak için SqlConnection dizeleri değiştirin.

Web hizmetini sınama

  1. Derlemeye ve Web hizmetini çalıştırmak için F5 tuşuna basın. Bir Web sayfası URL ile döndürülen bildirimi http://localhost/CSharpUpdateData/Service1.asmx. Bu Web sayfasında, Microsoft ınternet Explorer Web hizmetiyle etkileşim kurabilirsiniz.
  2. Service1.asmx Web sayfasında, GetData ' ı tıklatın. GetData Web yöntemi ile ilgili ayrıntıları görüntüleyen bir Web sayfası döndürülür dikkat edin.
  3. Web sayfaları kapatın.

İstemci uygulamasını oluşturma

  1. Yeni bir Visual C# Windows uygulaması projesi oluşturmak için aşağıdaki adımları izleyin:
    1. Visual Studio. NET'te Dosya menüsünden Yeni ' nin üzerine gelin ve sonra Project ' i tıklatın.
    2. Yeni proje) iletişim kutusunda, Project Types altında Visual C# Projects ' ı tıklatın ve şablonları altında Windows uygulama ' yı tıklatın. Varsayılan olarak, projeye Form1 eklenir.
  2. Araç kutusundan, bir Düğme denetimi ve bir DataGrid denetiminde Form1'e sürükleyin. Varsayılan olarak, denetimleri sırasıyla button1 ve dataGrid1 adlandırılır.
  3. BtnSave için button1 <a1>Name</a1> özelliğini değiştirmek ve sonra Kaydetbutton1 <a1>Text</a1> özelliğini değiştirin.
  4. Proje) menüsünde Add Web Reference ' ı tıklatın. Web hizmetiniz (Bu durumda, http://localhost/CSharpUpdateData/Service1.asmx türü), ENTER tuşuna basın ve Add Reference</a1>'ı tıklatın, URL yazın. Bu Web başvurusu için giriş Solution'ın içinde görünen bildirimi Explorer.
  5. Form1 sınıfı, bir form düzeyi üyesini DataSet için bildirmek için aşağıdaki kodu ekleyin:
           private System.Data.DataSet ds;
    					
  6. Formun kod görünümüne geçin ve Visual Studio. NET'in Form1_Load yöntemi oluşturduğu fark'ı çift tıklatın. Form1_Load yöntemine aşağıdaki kodu ekleyin:
        localhost.Service1 sv = new localhost.Service1();
        ds = sv.GetData ();
           
        dataGrid1.DataSource = ds;
        dataGrid1.DataMember = "Orders";
    					
  7. Form görünümüne geçin.
  8. Kaydet düğmesi için kod penceresi açın ve sonra da btnSave_Click olay işleyicisine aşağıdaki kodu ekleyin:
        localhost.Service1 sv = new localhost.Service1();
    
        DataSet MyChangedRows;
    
        dataGrid1.DataMember = "";
        dataGrid1.DataSource = null;
        //Pull out only what you must send over the wire.
        MyChangedRows = ds.GetChanges();
        MyChangedRows = sv.UpdateData(MyChangedRows);
    
        //You must accept changes on the DataSet because of a known problem. See Q313540.
    
        ds.AcceptChanges();
    
        ds.EnforceConstraints = false;
    
        //Merge in the parent rows first and then the child rows.
        ds.Merge(MyChangedRows.Tables["Orders"], false, MissingSchemaAction.Ignore);
        ds.Merge(MyChangedRows.Tables["details"], false, MissingSchemaAction.Ignore);
    
        //Accept changes that you have made to the DataSet.
        ds.AcceptChanges();
        //Turn on the integrity constraints that you turned off earlier.
        ds.EnforceConstraints = true;
    
        dataGrid1.DataSource = ds;
        dataGrid1.DataMember = "Orders";
    					

İstemci uygulamasını sınama

  1. Derleme ve istemci uygulamasını çalıştırmak için F5 tuşuna basın.
  2. DataGrid1 ' de, bazı verileri değiştirmek ve sonra da <a2>Kaydet</a2>'i tıklatın.

    Not: anahtar alanını değiştirin. Anahtar alanını değiştirirseniz, sunucu üzerinde bilgi tutarlılığı kesiliyor bildiren bir hata iletisi alırsınız.
  3. Alt satır için varolan bir üst satır ekleyin. Uyarı alt satıra doğru yabancı anahtar değerini otomatik olarak alır.
  4. Aşağıdaki değerleri yeni bir üst satır ve yeni bir alt satır ekleyin ve sonra da <a2>Kaydet</a2>'i tıklatın. Aşağıdaki anahtar değerleri göz önünde bulundurun:
    • Orders.CustomerID=RATTC
    • Orders.EmployeeID=1
    • Orders.OrderDate=2/2/2002
    • Details.ProductID=1
    • Details.UnitPrice=18
    • Details.Quantity=1
    • Details.Discount=0

Referanslar

Ek bilgi için, Microsoft Bilgi Bankası'ndaki makaleleri görüntülemek üzere aşağıdaki makale numaralarını tıklatın:
310143  (http://support.microsoft.com/kb/310143/EN-US/ ) NASıL YAPıLıR: ADO.NET ve Visual C# .NET kullanarak Web üzerinden Server veri güncelleştirme hizmeti.
313483  (http://support.microsoft.com/kb/313483/EN-US/ ) BILGI: Yol haritası ADO.NET DataAdapter nesneleri

Bu makaledeki bilginin uygulandığı durum:
  • Microsoft Visual C# .NET 2003 Standard Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
  • Microsoft ADO.NET 1.1
  • Microsoft ADO.NET 1.0
  • Microsoft ASP.NET 1.1
  • Microsoft ASP.NET 1.0
Anahtar Kelimeler: 
kbmt kbdatabinding kbhowtomaster kbsqlclient kbsystemdata KB320301 KbMttr
Otomatik TercümeOtomatik Tercüme
ÖNEMLİ: Bu makale, bir kişi tarafından çevrilmek yerine, Microsoft makine-çevirisi yazılımı ile çevrilmiştir. Microsoft size hem kişiler tarafından çevrilmiş, hem de makine-çevrisi ile çevrilmiş makaleler sunar. Böylelikle, bilgi bankamızdaki tüm makalelere, kendi dilinizde ulaşmış olursunuz. Bununla birlikte, makine tarafından çevrilmiş makaleler mükemmel değildir. Bir yabancının sizin dilinizde konuşurken yapabileceği hatalar gibi, makale; kelime dağarcığı, söz dizim kuralları veya dil bilgisi açısından yanlışlar içerebilir. Microsoft, içeriğin yanlış çevrimi veya onun müşteri tarafından kullanımından doğan; kusur, hata veya zarardan sorumlu değildir. Microsoft ayrıca makine çevirisi yazılımını sıkça güncellemektedir.
Makalenin İngilizcesi aşağıdaki gibidir:320301  (http://support.microsoft.com/kb/320301/en-us/ )