婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 在ASP.NET 2.0中操作數據之五十六:使用ObjectDataSource緩存數據

在ASP.NET 2.0中操作數據之五十六:使用ObjectDataSource緩存數據

熱門標簽:臨沂智能電話機器人加盟 400電話辦理怎么樣 聯通官網400電話辦理 百應電話機器人外呼系統 蘇州如何辦理400電話 網絡電話外呼系統上海 外呼電話機器人成本 西寧呼叫中心外呼系統線路商 地圖標注軟件免費下載

導言

  就計算機科學而言,caching就是將所需要的數據或信息的備份放在某個地方,便于快速訪問的這樣一個過程。以數據處理(data-driven)程序為例,程序的大部分時間浪費在數據查詢上。要提升這種程序的性能,通常的做法是將查詢結果存放在程序的存儲器里。

  ASP.NET 2.0提供了各種各樣的緩存方式。對web頁面和用戶控件可以通過output caching進行緩存;同樣我們可以通過ObjectDataSource 和SqlDataSource控件,在控件級(control level)對數據進行緩存;同時,ASP.NET的data cache提供了豐富的緩存接口(caching API),供頁面開發員通過編程緩存對象。在本文及接下來的3篇文章我們將對ObjectDataSource的緩存屬性以及data cache進行考察;我們也將探究如何在啟動時對application-wide數據進行緩存,以及通過使用SQL cache dependencies對緩存數據刷新。

主要的緩存要點

  由于緩存通過將數據的副本放置在一個便于快速訪問的地方來提高程序的總體性能。由于它僅僅是一個副本,當源數據發生改變時,副本不能同步更新。為此,頁面開發員應制定一個標準將其清除出內存,可以使用如下的2種方法之一:

  Time-based標準:向內存添加的條目(item),只能在內存里駐留固定或靈活(sliding)的一段時間。比如,開發者可設定一個時間段,比如60秒,當條目添加到內存后,不管訪問它的頻率有多高,60秒后就會被清除掉;如果是靈活(sliding)處理的話,當最后一次被訪問后,未再次被訪問的時間一旦超出60秒,也會被清除掉。

  Dependency-based標準:當向內存添加條目時為其分配一個從屬體(dependency),當條目對應的從屬體發生改變時將條目清除掉。從屬體可以是一個文件;另一個緩存條目;或者干脆是這兩者的混合體( combination);當然還可以是SQL cache dependencies,它可以向內存添加條目,當源數據改變時將條目清除掉。我們將在接下來的文章《使用SQL緩存依賴項SqlCacheDependency 》里詳細考察。

  不管是哪種標準,在條目被清除掉以前,我們都可以對其訪問。如果內存達到了它的極限,它會清除掉已有的條目后再添加新的條目。因此,當處理緩存數據時很重要的一點是我們要充分考慮到緩存數據已被清除的可能。在下一篇文章《在分層架構中緩存數據》我們考察采用哪種模式從內存訪問數據。

  緩存是提升程序性能的一種較為經濟的方法,就像Steven Smith在他的文章《ASP.NET Caching: Techniques and Best Practices:》里闡述的一樣:“緩存是獲得‘上佳'性能的一種好方法,不需要太多的時間和分析。… 存儲器也便宜,要獲得你期望的性能,靠緩存技術你需要花30秒;靠優化代碼和數據庫你可能要幾天乃至幾周時間…”

  雖然緩存可以顯而易見的提升系統性能,但并不是適用于所有的應用程序,比如某些實時(real-time)、頻繁更新數據的程序就不適合。
  但是對大部分程序而言,還是適用的。關于ASP.NET 2.0里的緩存的更多背景資料請參考ASP.NET 2.0 QuickStart Tutorials系列的Caching for Performance 部分。

第一步:創建Caching頁面

在我們開始以前,首先讓我們花些時間來添加包括本篇在內的最近四篇教程需要用到的頁面。我們先在項目中新建一個稱作Caching的文件夾,接下來,為目錄新增以下幾個頁面,并配置為使用Site.master母板頁。

Default.aspx
ObjectDataSource.aspx
FromTheArchitecture.aspx
AtApplicationStartup.aspx
SqlCacheDependencies.aspx


圖1:創建相關的ASP.NET頁面

像其它文件夾一樣,Caching文件夾里的Default.aspx頁面將本系列的文章顯示出來。記得用戶控件SectionLevelTutorialListing.ascx提供該功能,設計模式里將其拖到頁面上。


圖2:為Default.aspx頁面添加用戶控件SectionLevelTutorialListing.ascx

最后,將這些頁面添加到Web.sitemap文件里,特別的,放在“Working with Binary Data” siteMapNode>:之后:

siteMapNode title="Caching" url="~/Caching/Default.aspx"
 description="Learn how to use the caching features of ASP.NET 2.0.">
 siteMapNode url="~/Caching/ObjectDataSource.aspx"
 title="ObjectDataSource Caching"
 description="Explore how to cache data directly from the
 ObjectDataSource control." />
 siteMapNode url="~/Caching/FromTheArchitecture.aspx"
 title="Caching in the Architecture"
 description="See how to cache data from within the
 architecture." />
 siteMapNode url="~/Caching/AtApplicationStartup.aspx"
 title="Caching Data at Application Startup"
 description="Learn how to cache expensive or infrequently-changing
 queries at the start of the application." />
 siteMapNode url="~/Caching/SqlCacheDependencies.aspx"
 title="Using SQL Cache Dependencies"
 description="Examine how to have data automatically expire from the
 cache when its underlying database data is modified." />
/siteMapNode>

完成Web.sitemap文件的更新后,讓我們在瀏覽器里查看,左邊的菜單欄顯示caching章節的文章
圖3:網站地圖Site Map包含了Caching章節的文章

第二步:在Web Page頁面里展示產品

  本文考察怎樣使用ObjectDataSource控件內置(built-in)的緩存功能。在開始之前,我們首先需要創建一個頁面,用一個ObjectDataSource控件調用ProductsBLL class類獲取產品信息,再用GridView控件展示出來。

  首先打開Caching文件夾里的ObjectDataSource.aspx頁面。從工具箱拖一個GridView控件到頁面,設置其ID為Products,再從智能標簽里選擇將其綁定到一個ObjectDataSource控件,ID為ProductsDataSource。設該ObjectDataSource使用ProductsBLL class類。


圖4:設置ObjectDataSource控件使用ProductsBLL Class類

  在本頁面,我們要創建一個允許編輯的GridView控件,當ObjectDataSource控件里的緩存數據發生改變時,我們可以通過GridView的界面查看到底會發生什么。在SELECT標簽里選擇默認的GetProducts()方法, 但是在UPDATE標簽里選擇接受productName, unitPrice 和productID作為輸入參數的UpdateProduct()重載方法。


圖5:在UPDATE標簽里選擇重載的UpdateProduct()方法

  最后,在INSERT和DELETE標簽里選擇“(None)”,點完成按鈕。一旦完成“設置數據源向導”,Visual Studio會將ObjectDataSource控件的OldValuesParameterFormatString屬性設置為original_{0}。就像在前面的教程之16章《概述插入、更新和刪除數據》里探討的一樣,該屬性要么刪除掉,要么設置為{0},不然的話更新操作會報錯。

  此外,完成向導后,Visual Studio會將產品的所有數據列添加到GridView控件,將除了ProductName, CategoryName和UnitPrice之外的所有綁定列(BoundFields)刪除。然后,分別將上述3列的HeaderText屬性改為Product”, “Category”和“Price”。由于ProductName是必需的,將ProductName列轉變成模板列(TemplateField),在EditItemTemplate里添加一個RequiredFieldValidator控件;同樣的,將UnitPrice列也轉換成模板列,并添加一個CompareValidator控件,確保用戶輸入的是大于或等于0的有效的貨幣值。除此以外,你還可以作一些界面上的改進,比如使UnitPrice值居中,或分別對UnitPrice的只讀和編輯界面作一些格式化的處理。

  在GridView的智能標簽里點相關項啟動編輯、分頁、排序功能。

  注意:想回顧怎樣自定義GridView的編輯界面嗎?請參考前面的文章之20《定制數據修改界面》 


圖6:啟用GridView的編輯、排序、分頁功能。

完成GridView的修改后,GridView 和 ObjectDataSource的代碼聲明看起來像下面這樣:

asp:GridView ID="Products" runat="server" AutoGenerateColumns="False"
 DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
 AllowPaging="True" AllowSorting="True">
 Columns>
 asp:CommandField ShowEditButton="True" />
 asp:TemplateField HeaderText="Product" SortExpression="ProductName">
 EditItemTemplate>
 asp:TextBox ID="ProductName" runat="server"
 Text='%# Bind("ProductName") %>'>/asp:TextBox>
 asp:RequiredFieldValidator
 ID="RequiredFieldValidator1" Display="Dynamic"
 ControlToValidate="ProductName" SetFocusOnError="True"
 ErrorMessage="You must provide a name for the product."
 runat="server">*/asp:RequiredFieldValidator>
 /EditItemTemplate>
 ItemTemplate>
 asp:Label ID="Label2" runat="server"
 Text='%# Bind("ProductName") %>'>/asp:Label>
 /ItemTemplate>
 /asp:TemplateField>
 asp:BoundField DataField="CategoryName" HeaderText="Category"
 ReadOnly="True" SortExpression="CategoryName" />
 asp:TemplateField HeaderText="Price" SortExpression="UnitPrice">
 EditItemTemplate>
 $asp:TextBox ID="UnitPrice" runat="server" Columns="8"
 Text='%# Bind("UnitPrice", "{0:N2}") %>'>/asp:TextBox>
 asp:CompareValidator ID="CompareValidator1"
 ControlToValidate="UnitPrice" Display="Dynamic"
 ErrorMessage="You must enter a valid currency value with no
 currency symbols. Also, the value must be greater than
 or equal to zero."
 Operator="GreaterThanEqual" SetFocusOnError="True"
 Type="Currency" runat="server"
 ValueToCompare="0">*/asp:CompareValidator>
 /EditItemTemplate>
 ItemStyle HorizontalAlign="Right" />
 ItemTemplate>
 asp:Label ID="Label1" runat="server"
 Text='%# Bind("UnitPrice", "{0:c}") %>' />
 /ItemTemplate>
 /asp:TemplateField>
 /Columns>
/asp:GridView>

asp:ObjectDataSource ID="ProductsDataSource" runat="server"
 OldValuesParameterFormatString="{0}" SelectMethod="GetProducts"
 TypeName="ProductsBLL" UpdateMethod="UpdateProduct">
 UpdateParameters>
 asp:Parameter Name="productName" Type="String" />
 asp:Parameter Name="unitPrice" Type="Decimal" />
 asp:Parameter Name="productID" Type="Int32" />
 /UpdateParameters>
/asp:ObjectDataSource>

如圖7所示,GridView列出了每個產品的name, category和price信息。花幾分鐘測試頁面—對結果排序,查看分頁,編輯某條記錄。


圖7:顯示每條記錄的Name, Category和Price信息

第三步:考察ObjectDataSource如何請求數據

  ID為Products的GridView通過調用名為ProductsDataSource的ObjectDataSource的Select()方法檢索數據并將它顯示出來。該ObjectDataSource創建業務邏輯層的ProductsBLL class類的一個實例并調用它的GetProducts()方法,該方法又調用數據訪問層ProductsTableAdapter的GetProducts()方法。數據訪問層連接到數據庫Northwind,并執行已設置好了的SELECT查詢。查詢數據以NorthwindDataTable的形式返回到數據訪問層,該DataTable對象再依次傳回到業務邏輯層,ObjectDataSource、GridView控件。GridView控件為DataTable里的每一數據行(DataRow)創建一個GridViewRow對象,每個GridViewRow對象最終被編譯為HTML返回到客戶端,呈現在訪問者的瀏覽器里。

  任何時候,當GridView控件需要綁定時,按上述的事件發生順序執行。比如,首次登錄頁面;將數據從一個頁面傳遞到另一個頁面;在GridView里排序;通過GridView內建的編輯或刪除界面改動數據。當GridView的視圖(view sta被設為disabled時,每次頁面回傳時也會對GridView重新綁定;當然我們可以顯式地調用DataBind()方法來對GridView實施綁定。

  為了更清除地揭示從數據庫檢索數據的頻率,我們顯示一個消息,提示在某時程序在檢索數據。為此,在GridView控件上添加一個ID為ODSEvents的Label控件,清除其Text屬性,將其EnableViewState屬性設置為false。在Label控件下面再添加一個Button控件,設其Text屬性為“Postback”.


圖8:在GridView上添加Label 和 Button控件

在整個數據檢索過程中,首先觸發ObjectDataSource的Selecting事件,并調用其對應的已設置好的方法。為該事件創建一個事件處理器,添加如下的代碼:

protected void ProductsDataSource_Selecting(object sender,
 ObjectDataSourceSelectingEventArgs e)
{
 ODSEvents.Text = "-- Selecting event fired";
}

  每當ObjectDataSource開始檢索數據時,Label控件都會顯示文本“Selecting event fired”.

  在瀏覽器訪問該頁面。當首次登錄時,文本“Selecting event fired”就會顯示出來。點“Postback”按鈕時,我們注意到文本消失了(前提是你將GridView的EnableViewState屬性設置為默認值true)。這是因為當頁面回傳時,GridView通過它的視圖狀態(view state)載入數據進行重建(reconstructed),因此不再需要通過ObjectDataSource檢索數據庫來得到數據進行重建。然而,排序、分頁、編輯等都會促使GridView重新綁定到數據源,因此,文本“Selecting event fired”又出現了。


圖9:當GridView重新綁定到數據源時,顯示文本“Selecting event fired”


圖10:點“Postback” 按鈕導致GridView從視圖狀態“View State”獲取數據

  每次分頁、排序時都需要從數據庫檢索數據,這看起來有點浪費資源。即便GridView不支持排序和分頁,任何人每次第一次登錄頁面時都需要從數據庫檢索數據(如果將view state設置為disabled的話,每次頁面回轉也會檢索數據)。如果GridView對所有用戶顯示的數據都是一樣話,那么額外的數據庫查詢是浪費。我們可以對GetProducts()方法返回的數據進行緩存,再將GridView綁定到這些緩存數據。

第四步:用ObjectDataSource緩存數據

僅僅簡單的設置某些屬性,我們就可以讓ObjectDataSource對它的檢索數據自動的進行緩存。以下總結了ObjectDataSource控件的與緩存相關的屬性:

EnableCaching—必須設置為true,默認為false.

CacheDuration—緩存時間,以秒為單位。默認為0,只有當EnableCaching屬性設置為true,且CacheDuration設為大于0的值時ObjectDataSource控件才會緩存數據。

CacheExpirationPolicy—可設置為Absolute 或 Sliding。如果為Absolute,當它設為多少秒時,ObjectDataSource就會對檢索的數據緩存多少秒;如果為Sliding,當它設為多少秒時,一旦超過那么多秒沒有對緩存數據進行訪問,就終止緩存。默認為Absolute。

CacheKeyDependency—用該屬性將ObjectDataSource的緩存條目(entry)與現有的緩存從屬體關聯起來。利用可以它將緩存條目提前從內存清除掉。絕大多數情況下用該屬性把SQL cache dependency與ObjectDataSource的緩存關聯起來。這個話題我們將在后面的教程《使用SQL緩存依賴項SqlCacheDependency 》考察。

讓我們設置ID為ProductsDataSource的ObjectDataSource 的數據緩存時間為30秒。設其EnableCaching屬性為true;設其CacheDuration屬性為30;CacheExpirationPolicy屬性為默認的Absolute。


圖11:設置ObjectDataSource的緩存時間為30秒

  保存你的設置,并在瀏覽器里查看。當你第一次登錄頁面時,文本“Selecting event fired”會顯示出來,因為原始數據還未緩存。但你點“Postback”按鈕,或進行分頁,排序,或點編輯、取消按鈕時,文本“Selecting event fired”就不會顯示出來了。原因是只有當ObjectDataSource控件檢索數據時才會觸發Selecting事件;如果ObjectDataSource控件是從緩存里面獲取數據的話就不會觸發Selecting事件。

  過了30秒后,數據將從內存清除;或者調用ObjectDataSource控件的Insert, Update,或Delete方法的話數據也會被清除掉。因此,過了30秒后或點擊“Update”按鈕,編輯,取消按鈕,或排序、分頁的話就會促使ObjectDataSource檢索數據,觸發Selecting事件,文本“Selecting event fired”又會顯示出來。最后,再對檢索得到的數據進行緩存。

  注意:如果你看到文本“Selecting event fired”頻繁的出現,很可能是內存容量太小。如果沒有足夠的容量,ObjectDataSource添加到內存的數據可能被清除掉了。如果ObjectDataSource沒有或者只是偶爾地對數據緩存,請關閉一些應用程序來釋放掉內存,然后再試一次。

  圖12揭示了ObjectDataSource的緩存流程。當文本“Selecting event fired”出現在屏幕上時,那是因為數據沒有在緩存里找到,必須進行相關檢索。當文本消失時,那是因為數據進行了緩存。當從緩存得到了所需的數據時,沒有任何數據查詢執行。


圖12:ObjectDataSource在Data Cache里存儲和獲取數據

  每一個ASP.NET應用程序有它自己的數據緩存實例,所有的頁面和用戶都可以進行訪問。那意味著對于ObjectDataSource控件緩存的數據,所有登錄該頁面的用戶都可以訪問。來做個驗證,在一個瀏覽器里打開ObjectDataSource.aspx頁面,當第一次登錄該頁面時,文本“Selecting event fired”顯現出來(假定前面測試時緩存的數據到此時已經被清除掉了)。再開第二個瀏覽器,將第一個瀏覽器里的URL地址拷貝、粘貼過來。在第二個瀏覽器里,文本“Selecting event fired”并沒有顯示出來,因為它使用的是第一個瀏覽器頁面緩存的數據。

  當向內存添加檢索數據時,ObjectDataSource要用到一個叫cache key的值,該值包括:CacheDuration 和 CacheExpirationPolicy屬性的值;ObjectDataSource調用的業務對象的類型(type),它由TypeName 屬性指定(比如:ProductsBLL);SelectMethod 屬性的值,以及SelectParameters參數集里參數的name 和 values;StartRowIndex 和 MaximumRows屬性的值,它用來執行用戶自定義分頁(custom paging)。

  將這些屬性值組合在一起構成cache key值是為了對每一個緩存條目提供唯一的標識值。比如,在前面的教程里,我們使用ProductsBLL類的GetProductsByCategoryID(categoryID)方法來獲取某個指定類的所有產品。假如一個用戶在頁面查看飲料類(其CategoryID值為1)的產品信息,如果ObjectDataSource控件在進行數據緩存時忽略SelectParameters的值,當另一個用戶登錄頁面查看調味品類的產品信息時,恰好飲料類產品信息正好緩存在內存里,第二個用戶將會看到飲料類的產品信息,而非他想要的調味品類的產品信息。所以,當cache key值包含electParameters的值的話,ObjectDataSource緩存數據的時候就可以將調味品類和飲料類區分開來。

數據更新不同步(Stale Data)問題

  當調用ObjectDataSource控件的Insert, Update和 Delete其中一個方法時,它都會將緩存條目從內存清除掉。這樣做的好處在于當從頁面修改數據時將緩存的舊數據清除掉。然而,ObjectDataSource還是可能有將“未更新數據”(也就是源數據已經發生改變,而緩存的數據沒同步更新)顯示出來的情況。最簡單的例子是直接從數據庫修改數據,比如某個數據庫管理員運行一個腳本,修改數據庫里的某些記錄。

  在此,我們探討一種微妙的情況。雖然調用ObjectDataSource的數據修改方法時它會將緩存數據清除掉,但清除的是那些與ObjectDataSource的“屬性組合值”(combination of property)相匹配的緩存條目(比如CacheDuration, TypeName, SelectMethod等)。假如你有2個ObjectDataSources控件,它們更新相同的數據,當使用不同的SelectMethods 或 SelectParameters,當第一個ObjectDataSources控件更新某一行記錄而清除該行對應的緩存數據時,第二個ObjectDataSources控件仍然使用該行對應的緩存數據。我們來做個驗證,創建一個頁面,包含可編輯的GridView控件,其對應的ObjectDataSource控件設置為使用緩存,且調用ProductsBLL類的GetProducts()方法來獲取數據。在本頁(或另外創建一個頁面)再添加GridView 和ObjectDataSource控件,但是設置第二個ObjectDataSource控件調用GetProductsByCategoryID(categoryID)方法。由于這2個ObjectDataSource控件的SelectMethod屬性不同,因此它們各自有各自不同的緩存值。如果你在第一個GridView控件里編輯某個產品,然后在第二個GridView控件里重新綁定數據(比如分頁、排序等),我們在第二個GridView控件里看到該產品的值依然是“老的緩存數據”(而并不是第一個GridView控件修改后的值)

  簡而言之,如果你樂于使用“老的緩存數據”,那只有使用基于時間的緩存時間值(time-based expiries,也就是設置具體的緩存時間長度),如果對數據及時更新要求很高的話,將緩存時間設短點。如果不允許使用“老的緩存數據”的話,要么放棄緩存,要么使用SQL cache dependencies(你可以認為它是你緩存的數據庫數據)。我們將在后面探討SQL cache dependencies。

總結:

  在本文我們考察了ObjectDataSource內建的緩存功能。僅僅設置很少的屬性,我們可以將ObjectDataSource調用SelectMethod方法得到的數據進行緩存。其CacheDuration 和 CacheExpirationPolicy屬性指定了緩存的時間和類型(absolute或sliding)。而CacheKeyDependency屬性將ObjectDataSource的緩存實體與現有的緩存從屬體(cache dependency)關聯起來,一般是SQL cache dependencies。

  因為ObjectDataSource只是簡單地進行數據緩存,我們可以通過編程實現ObjectDataSource內建的這種功能。不過在表現層這樣做沒有意義,因為ObjectDataSource控件提供了該功能。不過我們可以在體系結構的其它層次實現緩存功能。為此,我們需要一個邏輯,它與ObjectDataSource調用的相同。在下一篇文章我們將考察如何在體系結構內部編程處理數據緩存。

  祝編程快樂!

作者簡介

  本系列教程作者 Scott Mitchell,著有六本ASP/ASP.NET方面的書,是4GuysFromRolla.com的創始人,自1998年以來一直應用 微軟Web技術。大家可以點擊查看全部教程《[翻譯]Scott Mitchell 的ASP.NET 2.0數據教程》,希望對大家的學習ASP.NET有所幫助。

您可能感興趣的文章:
  • 在ASP.NET 2.0中操作數據之五十七:在分層架構中緩存數據
  • 在ASP.NET 2.0中操作數據之五十八:在程序啟動階段緩存數據
  • 在ASP.NET 2.0中操作數據之五十九:使用SQL緩存依賴項SqlCacheDependency
  • 在ASP.NET 2.0中操作數據之六十:創建一個自定義的Database-Driven Site Map Provider
  • 在ASP.NET 2.0中操作數據之六十一:在事務里對數據庫修改進行封裝
  • 在ASP.NET 2.0中操作數據之六十二:GridView批量更新數據
  • 在ASP.NET 2.0中操作數據之六十三:GridView實現批量刪除數據
  • 在ASP.NET 2.0中操作數據之六十四:GridView批量添加數據
  • 在ASP.NET 2.0中操作數據之六十五:在TableAdapters中創建新的存儲過程
  • 在ASP.NET 2.0中操作數據之六十六:在TableAdapters中使用現有的存儲過程

標簽:臨夏 中衛 海西 清遠 聊城 平涼 慶陽 甘肅

巨人網絡通訊聲明:本文標題《在ASP.NET 2.0中操作數據之五十六:使用ObjectDataSource緩存數據》,本文關鍵詞  在,ASP.NET,2.0,中,操作,數據,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《在ASP.NET 2.0中操作數據之五十六:使用ObjectDataSource緩存數據》相關的同類信息!
  • 本頁收集關于在ASP.NET 2.0中操作數據之五十六:使用ObjectDataSource緩存數據的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    久久综合九色综合欧美98| 成人一区二区三区| 亚洲日本va午夜在线电影| 欧美高清一级片在线观看| 欧美激情一区二区| 国产精品视频你懂的| 国产精品美女久久久久久2018 | 一区二区三区不卡在线观看 | 日韩一区二区三区四区| 91精品国产综合久久蜜臀| 欧美浪妇xxxx高跟鞋交| 日韩欧美成人午夜| 久久精品视频在线免费观看| 国产日韩精品一区二区浪潮av | 欧美日韩在线观看一区二区 | 国产亲近乱来精品视频| 久久久久久久久99精品| 国产精品传媒入口麻豆| 亚洲制服丝袜av| 日本成人超碰在线观看| 国内精品伊人久久久久av影院| 精品伊人久久久久7777人| 岛国精品在线播放| 在线免费观看日韩欧美| 4438x成人网最大色成网站| 久久综合久久久久88| 中文字幕一区二区三| 亚洲综合av网| 69久久夜色精品国产69蝌蚪网| 91麻豆精品国产自产在线观看一区| 日韩一级黄色片| 亚洲欧美日韩中文播放| 午夜精品久久久久久久久久| 狠狠色丁香婷综合久久| 91蜜桃在线观看| 精品日韩一区二区| 性欧美大战久久久久久久久| 国产成人免费9x9x人网站视频| 在线精品视频小说1| 国产视频亚洲色图| 日本欧美加勒比视频| 91丝袜呻吟高潮美腿白嫩在线观看| 日韩午夜激情视频| 夜夜精品视频一区二区| 成人一级黄色片| 26uuu国产电影一区二区| 亚洲午夜电影在线| 91在线视频官网| 久久精品视频在线看| 毛片不卡一区二区| 欧美性xxxxxx少妇| 成人黄色a**站在线观看| 欧美精品日韩精品| 午夜精品久久久久久久久| 欧美日韩一本到| 亚洲国产欧美一区二区三区丁香婷| 99视频精品在线| 日韩不卡一区二区三区| 欧美电视剧免费全集观看| 精品在线播放免费| 亚洲成人在线网站| 91精品国产综合久久久蜜臀图片| 久久超级碰视频| 中文一区二区在线观看| 一本色道久久综合亚洲91 | 精品久久久久久亚洲综合网| 91成人国产精品| 亚洲欧美激情一区二区| 麻豆精品新av中文字幕| 韩日av一区二区| 国产喷白浆一区二区三区| 在线观看不卡视频| 在线观看欧美黄色| 亚洲免费观看在线视频| 91精品国产色综合久久ai换脸| 欧美日韩一级片在线观看| 亚洲免费色视频| 色悠久久久久综合欧美99| 亚洲欧美成aⅴ人在线观看| 91日韩在线专区| 亚洲制服丝袜在线| 久久免费偷拍视频| 风间由美一区二区av101| 国产精品久久久久久久裸模| 成人免费毛片app| 国产在线视频精品一区| 午夜欧美电影在线观看| 亚洲激情在线激情| 亚洲成a天堂v人片| 国内成人精品2018免费看| 一区二区久久久| 亚洲一区二区三区视频在线播放| 日韩激情av在线| 日韩av成人高清| 久久国产综合精品| 国产欧美日韩视频在线观看| 成人精品视频网站| 悠悠色在线精品| 91精品国产乱| 国产激情91久久精品导航| 亚洲欧美激情视频在线观看一区二区三区| 91浏览器在线视频| 蜜臀av在线播放一区二区三区 | 中文字幕免费不卡在线| 色域天天综合网| 人人爽香蕉精品| 国产精品久久毛片| 在线播放91灌醉迷j高跟美女 | 日韩精品一区二区在线观看| 国产一二三精品| 亚洲成人免费在线| 欧美激情在线看| 日韩小视频在线观看专区| 99久久精品免费看国产免费软件| 捆绑调教美女网站视频一区| 中文字幕亚洲区| 精品成a人在线观看| 欧美精品v日韩精品v韩国精品v| 国产一区激情在线| 男女男精品视频| 一区二区三区国产精品| 国产精品无圣光一区二区| 精品美女一区二区三区| 欧美性受极品xxxx喷水| 99免费精品在线观看| 国产麻豆成人精品| 老司机精品视频导航| 日韩成人午夜精品| 一区二区激情视频| 亚洲精品中文字幕在线观看| 中文字幕不卡在线观看| 久久久蜜臀国产一区二区| 日韩三区在线观看| 欧美日韩国产精选| 在线免费视频一区二区| www.66久久| 99精品视频在线播放观看| 91精品国产91久久久久久最新毛片 | 青青青爽久久午夜综合久久午夜| 亚洲色图制服丝袜| 中文字幕永久在线不卡| 国产精品国产三级国产aⅴ原创| 精品福利一二区| 精品国产麻豆免费人成网站| 日韩午夜激情免费电影| 日韩欧美的一区| 2021中文字幕一区亚洲| 精品成人免费观看| 欧美极品aⅴ影院| 国产精品色婷婷久久58| 亚洲图片欧美激情| 亚洲精品一卡二卡| 亚洲成人久久影院| 午夜视频一区二区三区| 日本v片在线高清不卡在线观看| 青草av.久久免费一区| 寂寞少妇一区二区三区| 国产成人精品一区二区三区四区 | 免费在线观看精品| 另类小说一区二区三区| 国产精品456露脸| 不卡欧美aaaaa| 欧美日韩一区中文字幕| 日韩欧美亚洲一区二区| 久久久精品蜜桃| 成人免费一区二区三区在线观看| 亚洲精品视频在线观看免费| 性做久久久久久免费观看欧美| 奇米在线7777在线精品| 国产精品中文字幕一区二区三区| 不卡av在线网| 欧美一区二区在线观看| 国产亚洲精品福利| 亚洲品质自拍视频| 日本成人在线网站| 成年人国产精品| 日韩亚洲欧美一区二区三区| 中文字幕 久热精品 视频在线 | 久久国产夜色精品鲁鲁99| 国产91精品露脸国语对白| 欧美视频中文一区二区三区在线观看| 日韩免费观看高清完整版| 国产精品成人免费在线| 日韩成人伦理电影在线观看| 国产 日韩 欧美大片| 在线综合+亚洲+欧美中文字幕| 久久久久久久网| 亚洲一区二区欧美| 国产成人av资源| 日韩一区二区三区四区| 亚洲激情av在线| 成人av在线资源| 日韩视频一区在线观看| 亚洲综合一区在线| 国产福利一区在线| 日韩精品一区二区三区视频播放 | 国产98色在线|日韩| 7777精品伊人久久久大香线蕉完整版| 国产精品久久久久久福利一牛影视| 日韩精品电影一区亚洲|