7. Bölüm: Özellik Ekleme

ali Stagner

Tailspin Spyworks, .NET platformu için güçlü ve ölçeklenebilir uygulamalar oluşturmanın ne kadar kolay olduğunu gösterir. Alışveriş, kullanıma alma ve yönetim dahil olmak üzere çevrimiçi mağaza oluşturmak için ASP.NET 4 ' te harika yeni özelliklerin nasıl kullanılacağını gösterir.

Bu öğretici serisi, Tailspin Spyworks örnek uygulamasını oluşturmak için kullanılan adımların tümünü ayrıntılarıyla ayrıntılardır. Bölüm 7, hesap incelemesi, Ürün İncelemeleri ve "popüler öğeler" ve "Ayrıca satın alınan" Kullanıcı denetimleri gibi ek özellikler ekler.

Özellik ekleme

Kullanıcılar kataloğumuza göz atabiliyor, bunları kendi alışveriş sepetine yerleştirse ve kullanıma alma işlemini tamamlayabilse de, sitemizi geliştirmek için dahil ettiğimiz birçok destekleyici özelliği vardır.

  1. Hesap Incelemesi (verilen siparişleri listeleyin ve ayrıntıları görüntüleyin.)
  2. İlk sayfaya belirli bir içeriğe özgü içerik ekleyin.
  3. Kullanıcıların katalogdaki ürünleri Incelemesine izin vermek için bir özellik ekleyin.
  4. Popüler öğeleri göstermek ve bu denetimi ön sayfaya yerleştirmek için bir kullanıcı denetimi oluşturun.
  5. "Ayrıca satın alınmış" Kullanıcı denetimi oluşturun ve ürün ayrıntıları sayfasına ekleyin.
  6. Kişi sayfası ekleyin.
  7. Hakkında bir sayfa ekleyin.
  8. Genel hata

Hesap Incelemesi

"Account" klasöründe, farklı bir OrderList. aspx adlı ve diğer adlandırılmış OrderDetails. aspx adlı iki. aspx sayfası oluşturun

OrderList. aspx, daha önce yaptığımız gibi GridView ve EntityDataSource denetimlerinden faydalanır.

<div class="ContentHead">Order History</div><br />

<asp:GridView ID="GridView_OrderList" runat="server" AllowPaging="True" 
              ForeColor="#333333" GridLines="None" CellPadding="4" Width="100%" 
              AutoGenerateColumns="False" DataKeyNames="OrderID" 
              DataSourceID="EDS_Orders" AllowSorting="True" ViewStateMode="Disabled" >
  <AlternatingRowStyle BackColor="White" />
  <Columns>
    <asp:BoundField DataField="OrderID" HeaderText="OrderID" ReadOnly="True" 
                    SortExpression="OrderID" />
    <asp:BoundField DataField="CustomerName" HeaderText="Customer" 
                    SortExpression="CustomerName" />
    <asp:BoundField DataField="OrderDate" HeaderText="Order Date" 
                    SortExpression="OrderDate" />
    <asp:BoundField DataField="ShipDate" HeaderText="Ship Date" 
                    SortExpression="ShipDate" />
    <asp:HyperLinkField HeaderText="Show Details" Text="Show Details" 
                 DataNavigateUrlFields="OrderID" 
                 DataNavigateUrlFormatString="~/Account/OrderDetails.aspx?OrderID={0}" />
  </Columns>
  <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
  <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
  <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
  <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
  <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
  <SortedAscendingCellStyle BackColor="#FDF5AC" />
  <SortedAscendingHeaderStyle BackColor="#4D0000" />
  <SortedDescendingCellStyle BackColor="#FCF6C0" />
  <SortedDescendingHeaderStyle BackColor="#820000" />
  <SortedAscendingCellStyle BackColor="#FDF5AC"></SortedAscendingCellStyle>
  <SortedAscendingHeaderStyle BackColor="#4D0000"></SortedAscendingHeaderStyle>
  <SortedDescendingCellStyle BackColor="#FCF6C0"></SortedDescendingCellStyle>
  <SortedDescendingHeaderStyle BackColor="#820000"></SortedDescendingHeaderStyle>
</asp:GridView>

<asp:EntityDataSource ID="EDS_Orders" runat="server" EnableFlattening="False" 
                      AutoGenerateWhereClause="True" 
                      Where="" 
                      OrderBy="it.OrderDate DESC"
                      ConnectionString="name=CommerceEntities"  
                      DefaultContainerName="CommerceEntities" 
                      EntitySetName="Orders" >
   <WhereParameters>
      <asp:SessionParameter Name="CustomerName" SessionField="UserName" />
   </WhereParameters>
</asp:EntityDataSource>

EntityDataSource, Kullanıcı oturumunun oturum açması sırasında bir oturum değişkeninde belirlediğimiz Kullanıcı adında (burada, bkz. parametre) filtrelenmiş Orders tablosundan kayıtlar seçer.

GridView 'un Hyperlinkalanındaki bu parametreleri de göz önünde bulabilirsiniz:

DataNavigateUrlFields="OrderID" DataNavigateUrlFormatString="~/Account/OrderDetails.aspx?OrderID={0}"

Bu, OrderDetails. aspx sayfasına bir QueryString parametresi olarak OrderID alanını belirten her ürün için sipariş ayrıntıları görünümünün bağlantısını belirtir.

OrderDetails. aspx

Siparişe ve bir FormView 'a erişmek için bir EntityDataSource denetimi kullanacağız ve tüm sipariş satır öğelerini görüntüleyen bir GridView ile başka bir EntityDataSource 'a sahiptir.

<asp:FormView ID="FormView1" runat="server" CellPadding="4" 
                             DataKeyNames="OrderID" 
                             DataSourceID="EDS_Order" ForeColor="#333333" Width="250px">
   <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
   <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
   <ItemTemplate>
      OrderID : <%# Eval("OrderID") %><br />
      CustomerName : <%# Eval("CustomerName") %><br />
      Order Date : <%# Eval("OrderDate") %><br />
      Ship Date : <%# Eval("ShipDate") %><br />
   </ItemTemplate>
   <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
   <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
</asp:FormView>
<asp:EntityDataSource ID="EDS_Order" runat="server"  EnableFlattening="False" 
                      ConnectionString="name=CommerceEntities" 
                      DefaultContainerName="CommerceEntities" 
                      EntitySetName="Orders" 
                      AutoGenerateWhereClause="True" 
                      Where="" 
                      EntityTypeFilter="" Select="">
   <WhereParameters>
      <asp:QueryStringParameter Name="OrderID" QueryStringField="OrderID" Type="Int32" />
   </WhereParameters>
</asp:EntityDataSource>

<asp:GridView ID="GridView_OrderDetails" runat="server" 
              AutoGenerateColumns="False" 
              DataKeyNames="ProductID,UnitCost,Quantity" 
              DataSourceID="EDS_OrderDetails" 
              CellPadding="4" GridLines="Vertical" CssClass="CartListItem" 
              onrowdatabound="MyList_RowDataBound" ShowFooter="True" 
              ViewStateMode="Disabled">
   <AlternatingRowStyle CssClass="CartListItemAlt" />
   <Columns>
     <asp:BoundField DataField="ProductID" HeaderText="Product ID" ReadOnly="True" 
                     SortExpression="ProductID"  />
     <asp:BoundField DataField="ModelNumber" HeaderText="Model Number"  
                     SortExpression="ModelNumber" />
     <asp:BoundField DataField="ModelName" HeaderText="Model Name" 
                     SortExpression="ModelName" />
     <asp:BoundField DataField="UnitCost" HeaderText="Unit Cost" ReadOnly="True" 
                     SortExpression="UnitCost" DataFormatString="{0:c}" />
     <asp:BoundField DataField="Quantity" HeaderText="Quantity" ReadOnly="True" 
                     SortExpression="Quantity" />
     <asp:TemplateField> 
       <HeaderTemplate>Item Total</HeaderTemplate>
       <ItemTemplate>
         <%# (Convert.ToDouble(Eval("Quantity")) *  Convert.ToDouble(Eval("UnitCost")))%>
       </ItemTemplate>
     </asp:TemplateField>
   </Columns>
   <FooterStyle CssClass="CartListFooter"/>
   <HeaderStyle  CssClass="CartListHead" />
 </asp:GridView> 
 <asp:EntityDataSource ID="EDS_OrderDetails" runat="server" 
                       ConnectionString="name=CommerceEntities" 
                       DefaultContainerName="CommerceEntities" 
                       EnableFlattening="False" 
                       EntitySetName="VewOrderDetails" 
                       AutoGenerateWhereClause="True" 
                       Where="">
   <WhereParameters>
     <asp:QueryStringParameter Name="OrderID" QueryStringField="OrderID" Type="Int32" />
   </WhereParameters>
</asp:EntityDataSource>

Arka plan kodu dosyasında (OrderDetails.aspx.cs), iki adet evetme tutuyoruz.

İlk olarak OrderDetails 'in her zaman bir OrderID aldığından emin olmanız gerekir.

protected void Page_Load(object sender, EventArgs e)
{
  if (String.IsNullOrEmpty(Request.QueryString["OrderId"]))
     {
     Response.Redirect("~/Account/OrderList.aspx");
     }
}

Ayrıca, satır öğelerinden sipariş toplamını hesaplamakta ve görüntüleriz.

decimal _CartTotal = 0;

protected void MyList_RowDataBound(object sender, GridViewRowEventArgs e)
{
  if (e.Row.RowType == DataControlRowType.DataRow)
     {
     TailspinSpyworks.Data_Access.VewOrderDetail myCart = new 
                                                        Data_Access.VewOrderDetail();
     myCart = (TailspinSpyworks.Data_Access.VewOrderDetail)e.Row.DataItem;
     _CartTotal += Convert.ToDecimal(myCart.UnitCost * myCart.Quantity);
     }
   else if (e.Row.RowType == DataControlRowType.Footer)
     {
     e.Row.Cells[5].Text = "Total: " + _CartTotal.ToString("C");
   }
}

Giriş sayfası

Default. aspx sayfasına bazı statik içerik ekleyelim.

İlk olarak bir "Içerik" klasörü ve bir Resimler klasörü oluşturacak (ana sayfada kullanılacak bir görüntü de ekleyeceğiz.)

Default. aspx sayfasının en alt yer tutucusuna aşağıdaki biçimlendirmeyi ekleyin.

<h2>
  <asp:LoginView ID="LoginView_VisitorGreeting" runat="server">
    <AnonymousTemplate>
       Welcome to the Store !
    </AnonymousTemplate>
    <LoggedInTemplate>
      Hi <asp:LoginName ID="LoginName_Welcome" runat="server" />. Thanks for coming back. 
    </LoggedInTemplate>
  </asp:LoginView>
</h2>

<p><strong>TailSpin Spyworks</strong> demonstrates how extraordinarily simple it is to create powerful, scalable applications for the .NET platform. </p>
<table>
  <tr>
    <td>               
      <h3>Some Implementation Features.</h3>
      <ul>
                <li><a href="#">CSS Based Design.</a></li>
                <li><a href="#">Data Access via Linq to Entities.</a></li>
                <li><a href="#">MasterPage driven design.</a></li>
                <li><a href="#">Modern ASP.NET Controls User.</a></li>
                <li><a href="#">Integrated Ajac Control Toolkit Editor.</a></li>
        </ul>
    </td>
    <td>
        <img src="Content/Images/SampleProductImage.gif" alt=""/>
    </td>
  </tr>
</table>
    
<table>
  <tr>
    <td colspan="2"><hr /></td>
  </tr>
  <tr>
    <td>               
        <!-- Popular Items -->
    </td>
    <td>  
      <center><h3>Ecommerce the .NET 4 Way</h3></center>
      <blockquote>
        <p>
        ASP.NET offers web developers the benefit of more that a decade of innovation. 
        This   demo leverages many of the latest features of ASP.NET development to     
        illustrate really simply building rich web applications with ASP.NET can be. 
        For more information about build web applications with ASP.NET please visit the 
        community web site at www.asp.net
        </p>
      </blockquote>
    </td>
  </tr>
</table>

<h3>Spyworks Event Calendar</h3>
<table>
  <tr class="rowH">
    <th>Date</th>
    <th>Title</th>
    <th>Description</th>
  </tr>
  <tr class="rowA">
    <td>June 01, 2011</td>
    <td>Sed vestibulum blandit</td>
    <td>
    Come and check out demos of all the newest Tailspin Spyworks products and experience 
    them hands on.
    </td>
  </tr>
  <tr class="rowB">
    <td>November 28, 2011</td>
    <td>Spyworks Product Demo</td>
    <td>
    Come and check out demos of all the newest Tailspin Spyworks products and experience 
    them hands on.
    </td>
  </tr>
  <tr class="rowA">
    <td>November 23, 2011</td>
    <td>Spyworks Product Demo</td>
    <td>
     Come and check out demos of all the newest Tailspin Spyworks products and experience 
     them hands on.
    </td>
  </tr>
  <tr class="rowB">
    <td>November 21, 2011</td>
    <td>Spyworks Product Demo</td>
    <td>
    Come and check out demos of all the newest Tailspin Spyworks products and experience 
    them hands on.
    </td>
  </tr>
</table>

Ürün Incelemeleri

İlk olarak, bir ürün incelemesi girmek için kullandığımız bir formun bağlantısını içeren bir düğme ekleyeceğiz.

<div class="SubContentHead">Reviews</div><br />
<a id="ReviewList_AddReview" href="ReviewAdd.aspx?productID=<%# Eval("ProductID") %>">
   <img id="Img2" runat="server" 
        src="~/Styles/Images/review_this_product.gif" alt="" />
</a>

ProductID 'yi sorgu dizesinde geçirdiğimiz unutulmamalıdır

Daha sonra, BelgeAdı \ Add. aspx adlı sayfayı ekleyelim

Bu sayfa, ASP.NET AJAX denetim araç setini kullanacaktır. Daha önce yapmadıysanız, DevExpress 'den indirebilirsiniz ve burada https://www.asp.net/learn/ajax-videos/video-76.aspxVisual Studio ile kullanmak üzere araç takımını ayarlamaya yönelik yönergeler vardır.

Tasarım modunda, araç kutusu ' ndan denetimleri ve Doğrulayıcıları sürükleyin ve aşağıdaki gibi bir form oluşturun.

Biçimlendirme şuna benzer şekilde görünecektir.

<asp:ToolkitScriptManager ID="ToolkitScriptManager1" runat="server">
</asp:ToolkitScriptManager>
<div class="ContentHead">Add Review - <asp:label id="ModelName" runat="server" /></div>
<div>
  <span class="NormalBold">Name</span><br />
  <asp:TextBox id="Name" runat="server" Width="400px" /><br />
  <asp:RequiredFieldValidator runat="server" id="RequiredFieldValidator1" 
                              ControlToValidate="Name" 
                              Display="Dynamic" 
                              CssClass="ValidationError" 
                              ErrorMessage="'Name' must not be left blank."  /><br />
  <span class="NormalBold">Email</span><br />
  <asp:TextBox id="Email" runat="server" Width="400px" /><br />
  <asp:RequiredFieldValidator runat="server" id="RequiredFieldValidator2" 
                              ControlToValidate="Email" Display="Dynamic" 
                              CssClass="ValidationError" 
                              ErrorMessage="'Email' must not be left blank." />
  <br /><hr /><br />
  <span class="NormalBold">Rating</span><br /><br />
  <asp:RadioButtonList ID="Rating" runat="server">
    <asp:ListItem value="5" selected="True" 
             Text='<img src="Styles/Images/reviewrating5.gif" alt=""> (Five Stars) '  />
    <asp:ListItem value="4" selected="True" 
             Text='<img src="Styles/Images/reviewrating4.gif" alt=""> (Four Stars) '  />
    <asp:ListItem value="3" selected="True" 
             Text='<img src="Styles/Images/reviewrating3.gif" alt=""> (Three Stars) '  />
    <asp:ListItem value="2" selected="True" 
             Text='<img src="Styles/Images/reviewrating2.gif" alt=""> (Two Stars) '  />
    <asp:ListItem value="1" selected="True" 
             Text='<img src="Styles/Images/reviewrating1.gif" alt=""> (One Stars) '  />
  </asp:RadioButtonList>
  <br /><hr /><br />
  <span class="NormalBold">Comments</span><br />
  <cc1:Editor ID="UserComment" runat="server" />
  <asp:RequiredFieldValidator runat="server" id="RequiredFieldValidator3" 
                              ControlToValidate="UserComment" Display="Dynamic" 
                              CssClass="ValidationError" 
                              ErrorMessage="Please enter your comment." /><br /><br />
  <asp:ImageButton ImageURL="Styles/Images/submit.gif" runat="server" 
                   id="ReviewAddBtn" onclick="ReviewAddBtn_Click" />
  <br /><br /><br />
</div>

İncelemeleri girebilmemiz için artık bu İncelemeleri ürün sayfasında görüntülemesine olanak tanır.

Bu biçimlendirmeyi ProductDetails. aspx sayfasına ekleyin.

<asp:ListView ID="ListView_Comments" runat="server" 
              DataKeyNames="ReviewID,ProductID,Rating" DataSourceID="EDS_CommentsList">
  <ItemTemplate>
    <tr>
      <td><%# Eval("CustomerName") %></td>
      <td>
        <img src='Styles/Images/ReviewRating_d<%# Eval("Rating") %>.gif' alt="">
        <br />
      </td>
      <td>
        <%# Eval("Comments") %>
      </td>
    </tr>
  </ItemTemplate>
  <AlternatingItemTemplate>
    <tr>
      <td><%# Eval("CustomerName") %></td>
      <td>
        <img src='Styles/Images/ReviewRating_da<%# Eval("Rating") %>.gif' alt="">
        <br />
      </td>
      <td><%# Eval("Comments") %></td>
    </tr>
  </AlternatingItemTemplate>
   <EmptyDataTemplate>
     <table runat="server">
       <tr><td>There are no reviews yet for this product.</td></tr>
     </table>
  </EmptyDataTemplate>
  <LayoutTemplate>
    <table runat="server">
      <tr runat="server">
        <td runat="server">
          <table ID="itemPlaceholderContainer" runat="server" border="1">
            <tr runat="server">
              <th runat="server">Customer</th>
              <th runat="server">Rating</th>
              <th runat="server">Comments</th>
             </tr>
             <tr ID="itemPlaceholder" runat="server"></tr>
           </table>
         </td>
       </tr>
       <tr runat="server">
         <td runat="server">
           <asp:DataPager ID="DataPager1" runat="server">
             <Fields>
               <asp:NextPreviousPagerField ButtonType="Button" 
                                           ShowFirstPageButton="True"
                                           ShowLastPageButton="True" />
             </Fields>
           </asp:DataPager>
         </td>
       </tr>
     </table>
  </LayoutTemplate>
</asp:ListView>
<asp:EntityDataSource ID="EDS_CommentsList" runat="server"  EnableFlattening="False" 
                       AutoGenerateWhereClause="True" 
                       EntityTypeFilter="" 
                       Select="" Where=""
                       ConnectionString="name=CommerceEntities" 
                       DefaultContainerName="CommerceEntities" 
                       EntitySetName="Reviews">
   <WhereParameters>
    <asp:QueryStringParameter Name="ProductID" QueryStringField="productID"  
                                               Type="Int32" />
  </WhereParameters>
</asp:EntityDataSource>

Uygulamamızı şimdi çalıştırmak ve bir ürüne gitmek, müşteri incelemeleri dahil ürün bilgilerini gösterir.

Popüler öğeler denetimi (Kullanıcı denetimleri oluşturma)

Web sitenizdeki satışları artırmak için, "müstehcen satış" popüler veya ilgili ürünlere birkaç özellik ekleyeceğiz.

Bu özelliklerden ilki, ürün kataloğumuza ait daha popüler ürünün bir listesi olacaktır.

Uygulamamızın giriş sayfasında en çok satılan öğeleri göstermek için bir "Kullanıcı denetimi" oluşturacağız. Bu bir denetim olacağı için, Visual Studio tasarımcısında denetimi istediğiniz herhangi bir sayfada sürükleyip bırakarak bu denetimi herhangi bir sayfada kullanabiliriz.

Visual Studio 'nun Çözüm Gezgini ' nde çözüm adına sağ tıklayın ve "denetimler" adlı yeni bir dizin oluşturun. Bunun yapılması gerekli olmasa da, "denetimler" dizinindeki tüm Kullanıcı denetimlerimizi oluşturarak projemizi düzenli tutmaya yardımcı olacak.

Denetimler klasörüne sağ tıklayın ve "yeni öğe" yi seçin:

"Popularıtems" denetiimizin bir adını belirtin. Kullanıcı denetimleri için dosya uzantısının. ascx değil. aspx olduğunu unutmayın.

Popüler öğelerimiz Kullanıcı denetimi, aşağıdaki gibi tanımlanacak.

<%@ OutputCache Duration="3600" VaryByParam="None" %>
<div class="MostPopularHead">Our most popular items this week</div>
<div id="PanelPopularItems" runat="server">
  <asp:Repeater ID="RepeaterItemsList" runat="server">
    <HeaderTemplate></HeaderTemplate>
      <ItemTemplate>               
        <a class='MostPopularItemText' 
           href='ProductDetails.aspx?productID=<%# Eval("ProductId") %>'>
                                               <%# Eval("ModelName") %></a><br />              
      </ItemTemplate>
    <FooterTemplate></FooterTemplate>
  </asp:Repeater>
</div>

Burada, bu uygulamada henüz kullandığımız bir yöntemi kullanıyoruz. Yineleyici denetimini kullandık ve bir veri kaynağı denetimi kullanmak yerine, yineleyici denetimini bir LINQ to Entities sorgusunun sonuçlarına bağlamamız yapıyoruz.

Denetiminizin arkasındaki kodda aşağıdaki gibi yaptık.

using TailspinSpyworks.Data_Access;

protected void Page_Load(object sender, EventArgs e)
{
  using (CommerceEntities db = new CommerceEntities())
    {
    try
      {
      var query = (from ProductOrders in db.OrderDetails
                        join SelectedProducts in db.Products on ProductOrders.ProductID  
                        equals SelectedProducts.ProductID
                        group ProductOrders by new
                            {
                            ProductId = SelectedProducts.ProductID,
                            ModelName = SelectedProducts.ModelName
                            } into grp
                        select new
                            {
                            ModelName = grp.Key.ModelName,
                            ProductId = grp.Key.ProductId,
                            Quantity = grp.Sum(o => o.Quantity)
                            } into orderdgrp where orderdgrp.Quantity > 0 
                        orderby orderdgrp.Quantity descending select orderdgrp).Take(5);

                    RepeaterItemsList.DataSource = query;
                    RepeaterItemsList.DataBind(); 
      }
    catch (Exception exp)
      {
      throw new Exception("ERROR: Unable to Load Popular Items - " + 
                           exp.Message.ToString(), exp);
      }
    }
}

Ayrıca Denetim işaretimizin en üstündeki bu önemli satırı göz önünde bulundurulın.

<%@ OutputCache Duration="3600" VaryByParam="None" %>

En popüler öğeler dakika temelinde değiştirilmeyeceği için uygulamamız performansını artırmak üzere bir aching yönergesi ekleyebiliriz. Bu yönerge, Denetim kodunun yalnızca, denetimin önbelleğe alınan çıktısı zaman aşımına uğradığında yürütülmesine neden olur. Aksi takdirde, denetimin çıktısının önbelleğe alınmış sürümü kullanılacaktır.

Şimdi yaptığımız tek şey, default. aspx sayfamızda yeni denetimimizi içerir.

Bir denetimin örneğini varsayılan formumuzu Aç sütununa yerleştirmek için sürükle ve bırak öğesini kullanın.

Uygulamamızı çalıştırdığımızda, giriş sayfasında en popüler öğeler görüntülenir.

"Ayrıca satın alınan" denetim (parametrelerle Kullanıcı denetimleri)

Oluşturacağımız ikinci Kullanıcı denetimi, bağlam özelliği ekleyerek bir sonraki düzeye göre daha fazla satıyor olacaktır.

En üstteki "Ayrıca satın alınan" öğeleri hesaplama mantığı önemsiz değildir.

"Ayrıca satın almış olan" denetim, seçili olan ProductID için OrderDetails kayıtlarını (daha önce satın alınan) seçer ve bulunan her benzersiz sipariş için OrderID 'leri alacak.

Ardından, tüm bu siparişlerden ürünleri Al ' ı seçeceğiz ve satın alınan miktarları toplammız gerekir. Ürünleri bu miktar toplamına göre sıralayacak ve ilk beş öğeyi görüntüleyecek.

Bu mantığın karmaşıklığı verildiğinde, bu algoritmayı saklı yordam olarak uygulayacağız.

Saklı yordam için T-SQL aşağıdaki gibidir.

ALTER PROCEDURE dbo.SelectPurchasedWithProducts
 @ProductID int
AS
        SELECT  TOP 5 
    OrderDetails.ProductID,
    Products.ModelName,
    SUM(OrderDetails.Quantity) as TotalNum

FROM    
    OrderDetails
  INNER JOIN Products ON OrderDetails.ProductID = Products.ProductID

WHERE   OrderID IN 
(
    /* This inner query should retrieve all orders that have contained the productID */
    SELECT DISTINCT OrderID 
    FROM OrderDetails
    WHERE ProductID = @ProductID
)
AND OrderDetails.ProductID != @ProductID 

GROUP BY OrderDetails.ProductID, Products.ModelName 

ORDER BY TotalNum DESC
RETURN

Bu saklı yordamın (SelectPurchasedWithProducts) uygulamamıza dahil ettiğimiz sırada olduğunu ve belirttiğimiz Varlık Veri Modeli oluşturduğumuzdan, gereken tablo ve görünümlere ek olarak, Varlık Veri Modeli Bu saklı yordamı içermelidir.

Saklı yordama Varlık Veri Modeli erişmek için, işlevi içeri aktarmanız gerekir.

Çözüm Gezgini 'ndeki Varlık Veri Modeli çift tıklayarak tasarımcıda açın ve model tarayıcısını açın, sonra tasarımcıya sağ tıklayıp "Işlev Içeri aktarma Ekle" seçeneğini belirleyin.

Bu işlem, bu iletişim kutusunu açar.

Yukarıda gördüğünüz gibi alanları doldurun, "SelectPurchasedWithProducts" öğesini seçin ve içeri aktarılan işlevimizin adı için yordam adını kullanın.

"Tamam" a tıklayın.

Bunu yaptıktan sonra, modeldeki başka herhangi bir öğe olabileceğinden, saklı yordama göre programlayabilirsiniz.

Bu nedenle, "denetimlerimiz" klasöründe AlsoPurchased. ascx adlı yeni bir kullanıcı denetimi oluşturun.

Bu denetimin biçimlendirmesi, Popularıtems denetimine çok tanıdık gelecektir.

<div>
<div class="MostPopularHead">
<asp:Label ID="LabelTitle" runat="server" Text=" Customers who bought this also bought:"></asp:Label></div>
<div id="PanelAlsoBoughtItems" runat="server">
    <asp:Repeater ID="RepeaterItemsList" runat="server">
       <HeaderTemplate></HeaderTemplate>
          <ItemTemplate>               
             <a class='MostPopularItemText' href='ProductDetails.aspx?productID=<%# Eval("ProductId") %>'><%# Eval("ModelName") %></a><br />              
          </ItemTemplate>
       <FooterTemplate></FooterTemplate>
    </asp:Repeater>
</div>
</div>

Önemli farkı, öğenin işlenmesi, ürüne göre farklı olacağı için çıktıyı önbelleğe alma işlemlerdir.

ProductID, denetimin bir "özelliği" olacaktır.

private int _ProductId;

public int ProductId
{
get { return _ProductId ; }
set { _ProductId = Convert.ToInt32(value); }
}

Denetimin PreRender olay işleyicisinde üç şey yapmak için göz yorduk.

  1. ProductID 'nin ayarlandığından emin olun.
  2. Geçerli bir ürünle satın alınmış ürünler olup olmadığını görün.
  3. Bazı öğelerin #2 belirlendiği şekilde çıkışını yapın.

Saklı yordamı model aracılığıyla çağırmanın ne kadar kolay olduğunu öğrenin.

//--------------------------------------------------------------------------------------+
protected void Page_PreRender(object sender, EventArgs e)
{
  if (_ProductId < 1)
     {
     // This should never happen but we could expand the use of this control by reducing 
     // the dependency on the query string by selecting a few RANDOME products here. 
     Debug.Fail("ERROR : The Also Purchased Control Can not be used without 
                         setting the ProductId.");
     throw new Exception("ERROR : It is illegal to load the AlsoPurchased COntrol 
                                  without setting a ProductId.");
     }
      
  int ProductCount = 0;
  using (CommerceEntities db = new CommerceEntities())
    {
    try
      {
      var v = db.SelectPurchasedWithProducts(_ProductId);
      ProductCount = v.Count();
      }
    catch (Exception exp)
      {
      throw new Exception("ERROR: Unable to Retrieve Also Purchased Items - " + 
                                  exp.Message.ToString(), exp);
      }
    }

  if (ProductCount > 0)
     {
     WriteAlsoPurchased(_ProductId);              
     }
  else
     {
     WritePopularItems();
     }
}

"Ayrıca satın alındı" olduğunu belirlemekten sonra, yineleyicisi 'ni sorgu tarafından döndürülen sonuçlara bağlayabiliriz.

//-------------------------------------------------------------------------------------+
private void WriteAlsoPurchased(int currentProduct)
{
  using (CommerceEntities db = new CommerceEntities())
        {
        try
          {
          var v = db.SelectPurchasedWithProducts(currentProduct);
          RepeaterItemsList.DataSource = v;
          RepeaterItemsList.DataBind();
          }
         catch (Exception exp)
          {
          throw new Exception("ERROR: Unable to Write Also Purchased - " + 
                                                          exp.Message.ToString(), exp);
          }
        }
}

"Ayrıca satın alınmış" öğeler yoksa kataloğumuzdan diğer popüler öğeleri görüntüleriz.

//--------------------------------------------------------------------------------------+
private void WritePopularItems()
{
  using (CommerceEntities db = new CommerceEntities())
    {
    try
      {
      var query = (from ProductOrders in db.OrderDetails
                   join SelectedProducts in db.Products on ProductOrders.ProductID 
                   equals SelectedProducts.ProductID
                   group ProductOrders by new
                         {
                         ProductId = SelectedProducts.ProductID,
                         ModelName = SelectedProducts.ModelName
                         } into grp
                   select new
                         {
                         ModelName = grp.Key.ModelName,
                         ProductId = grp.Key.ProductId,
                         Quantity = grp.Sum(o => o.Quantity)
                         } into orderdgrp
                   where orderdgrp.Quantity > 0
                   orderby orderdgrp.Quantity descending
                   select orderdgrp).Take(5);
                   
      LabelTitle.Text = "Other items you might be interested in: ";
      RepeaterItemsList.DataSource = query;
      RepeaterItemsList.DataBind();
      }
    catch (Exception exp)
      {
      throw new Exception("ERROR: Unable to Load Popular Items - " + 
                                                        exp.Message.ToString(), exp);
      }
    }
}

"Ayrıca satın alınan" öğeleri görüntülemek için ProductDetails. aspx sayfasını açın ve AlsoPurchased denetimini, bu konumda görünmesini sağlamak üzere Çözüm Gezgini 'nden sürükleyin.

<table  border="0">
  <tr>
     <td>
       <img src='Catalog/Images/<%# Eval("ProductImage") %>'  border="0" 
                                                   alt='<%# Eval("ModelName") %>' />
     </td>
     <td><%# Eval("Description") %><br /><br /><br />  
         <uc1:AlsoPurchased ID="AlsoPurchased1" runat="server" />                 
     </td>
   </tr>
</table>

Bu işlem, ProductDetails sayfasının en üstünde bulunan denetime bir başvuru oluşturur.

<%@ Register src="Controls/AlsoPurchased.ascx" tagname="AlsoPurchased" tagprefix="uc1" %>

AlsoPurchased Kullanıcı denetimi bir ProductID numarası gerektirdiğinden, sayfanın geçerli veri modeli öğesine karşı bir eval ekstresi kullanarak denetimizin ProductID özelliğini ayarlayacağız.

Şimdi oluşturup çalıştırdığımızda bir ürüne gözattığınızda, "Ayrıca satın alındı" öğelerini görtik.