精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

使用LINQ和ADO.NET創建Silverlight程序

原創
開發 后端
以數據為中心的Web應用程序變得越來越重要,使用Silverlight 2、LINQ和ADO.NET很容易創建富的、以數據為驅動的Web應用程序,本文向你展示創建Silverlight應用程序的基礎知識,如果將其連接到數據源后你的程序會變得更加閃亮。

51CTO.com獨家特稿】在Silverlight中可以創建行業和其它以數據為中心的應用系統,但在Silverlight中處理數據不是一件容易的事情,由于Silverlight包括許多處理數據和支持Web Service及XML的工具,但這些工具僅代表跨過防火墻進行數據訪問的最基礎的部分。

常見的數據訪問策略是使用Web Service和客戶端LINQ共同實現的,如果你正在修改現有Web Service端點強化你的Silverlight應用程序,那么我推薦你使用這個方法。但如果你在使用Silverlight創建一個新的Web Service,就沒有必要這么做了。

對一個典型的Web Service層而言,你在服務器上實現一個傳統的數據訪問策略(自定義業務對象、LINQ to SQL、實體框架、Nhibernate等)通過Web Service暴露數據對象,Web Service僅僅是數據訪問策略下面的網關。

但為了開啟完整的數據連通性,你必須要映射四個數據操作(創建、讀取、更新和刪除)到Web Service方法,下面是一個簡單的支持Product類的service contract,注意我在本文中使用的都是C#。

例1 Product Web Service的Service Contract

[ServiceContract]
public interface ICustomerService
{
  [OperationContract]
  List GetAllProducts();
  [OperationContract]
  Product GetProduct(int productID);
  [OperationContract]
  List GetAllProductsWithCategories();
  [OperationContract]
  Product SaveProduct(Product productToSave);
  [OperationContract]
  void DeleteProduct(Product productToDelete);
}

創建一套服務來處理應用程序完整的數據模型可能是相當費時的,正如這個例子中顯示的,特殊特性的操作可能導致Web Service非常臃腫,換句話說,Web Service將有新的要求和操作要增加,甚至包括不屬于核心業務域的操作。

在例1中你看到GetAllProductsWithCategories操作默認用于檢索Product和分類。即使添加排序、過濾和分頁機制到這個簡單的例子你也不要感到驚訝,如果有一個簡單的方法支持數據操作(如查詢、排序、過濾等)不用每次都手動構建這些機制那將是非常吸引人的,ADO.NET Data Service就正是為此而生的。

ADO.NET Data Service

ADO.NET Data Service的目標是為數據模型提供Web訪問端點,這些端點提供了數據排序、過濾、調整和分頁功能,因此開發人員就不需要在自己去編寫這部分代碼了,實際上,每個端點都是LINQ查詢的起點,就從這個端點上你就可以查詢你想要查找的數據。

但不要認為ADO.NET Data Service是另一個數據訪問策略,實際上,ADO.NET Data Service不執行任何直接的數據訪問操作,它位于數據訪問的上層,圖1顯示了ADO.NET Data Service和它在一個應用程序架構中的位置。

 

圖 1 ADO.NET Data Service層

由于ADO.NET Data Service依賴于數據訪問程序完成真實的數據訪問工作,你必須指定這個方法該如何做,在ADO.NET Data Service中,每個服務(Service)必須回到開啟LINQ的提供程序的后面,實際上,每個端點就是一個Iqueryable端點,因此ADO.NET Data Service支持任何支持Iqueryable的對象。

創建服務(Service)

當你將ADO.NET Data Service添加到你的項目中時,會創建一個新的.svc文件,代表一個服務的類,和Web Service不同,你不需要自己親自實現服務的操作,但要允許DataService類處理這些工作,為了運行這些服務,有兩個小任務必須執行。首先,DataService類需要一個類型參數叫做上下文對象,它是將數據作為服務暴露的類,當你的服務從關系數據庫暴露數據時,這個類是從實體框架(EntityFramework)的ObjectContext或LINQ to SQL的DataContext衍生而來的。

//使用我的NorthwindEntities上下文對象(context object)作為服務(Service)的數據源

public class Products : DataService

上下文對象沒有基數類要求,實際上,你可以創建你自己的上下文對象,只要它的屬性實現了Iqueryable接口,ADO.NET Data Service將會以端點形式暴露這些屬性:

public class StateContext
{
  StateList _states = new StateList();
  public IQueryable States 
  {
    get { return _states.AsQueryable(); } 
  }
}

InitializeService調用中,你可以使用IdataServiceConfiguration對象指定什么類型的許可允許進入服務,ADO.NET Data Service使用名詞和動詞具體指定許可,如例2所示:

例2 設置訪問規則

//這個方法只被調用一次初始化服務端策略
public static void InitializeService(IDataServiceConfiguration config)
{
  //只允許我們讀取和更新Products實體,不允許刪除和創建
  config.SetEntitySetAccessRule("Products", 
                                EntitySetRights.AllRead | 
                                EntitySetRights.WriteUpdate);
  //只允許讀取Category和Suppliers實體
  config.SetEntitySetAccessRule("Categories", EntitySetRights.AllRead);
  config.SetEntitySetAccessRule("Suppliers", EntitySetRights.AllRead);
}

完成這個之后,你可以直接瀏覽服務了,它將會顯示每個端點的原子反饋信息,為了調試ADO.NET Data Service,我建議你禁用Internet Explorer的RSS 反饋視圖,或使用另一個瀏覽器查看服務的XML格式。

#p#

查詢和更新數據

ADO.NET Data Service將服務作為具有代表性的狀態轉換器(Representational State Transfer (REST))暴露,它是一個基礎服務,不是基于SOAP的服務,這意味著要替換掉SOAP封包,服務響應的有效負載只包括數據,不包括原數據(metadata),所有請求都使用HTTP動詞(GET,PUT,POST等)和請求URI描述,假定你有一個如圖2所示的模型描述Products,Categories和Suppliers,ADO.NET Data Service服務將會產生三個端點,每個實體集一個,URI為了確定一個模型中的實體集,只需要使用服務的地址和端點的名字就可以了:http://localhost/{服務名}/{端點名}或http://localhost/Product.svc/Products

圖 2 數據模型示例

URI語法支持許多不同的特性,包括檢索特殊的實體,對結果進行排序、過濾、分頁和調整。

ADO.NET Data Service使用這些URI風格的查詢將數據返回給服務的用戶,目前支持兩個序列化格式(將來的版本很可能會進行擴展):JavaScript對象標記(JavaScript Object Notation即JSON)和基于原子的XML(Atom-based XML)。JSON對于客戶端Web代碼非常有吸引力,而Atom是基于XML的格式,因此需要借助XML解析器。

ADO.NET Data Service在查詢中使用標準的HTTP訪問頭來確定向客戶端返回什么格式,如果你從客戶端(如一個瀏覽器)發出一個請求可以破壞XML,如果你不通過Accept頭指定一個優先選用的格式,默認將使用Atom作為返回的格式。

查詢數據只是解決方案的一部分,我們的最終目標是同時支持查詢和更新,為了支持這些要求,ADO.NET Data Service映射了四個最基本的數據訪問操作到基本的HTTP動詞(如表1所示):

數據訪問動詞 HTTP動詞
Create POST
Read GET
Update PUT
Delete DELETE

表 1 數據訪問動詞 vs HTTP動詞

通過使用這些動詞,ADO.NET Data Service讓服務的用戶可以利用所有的數據操作類型,而不用為不同類型創建專門的端點。使用ADO.NET Data Service更新數據的唯一要求是在數據訪問技術下支持Iupdatable接口,這個接口定義了如何從ADO.NET Data Service更新和傳播到數據源。

Silverlight 2.0客戶端庫

如果你使用ADO.NET Data Service通過URI語法和操作XML來進行查詢和更新數據,你可能會得到你想要的許多功能,但你仍然要自行構建一些管道,ADO.NET Data Service客戶端庫的引入就是要解決這個問題,這個庫允許你直接在Silverlight程序中進行LINQ查詢,由客戶端庫將LINQ查詢翻譯成HTTP查詢或更新請求。

首先,你需要生成一些代碼,這些代碼讀取ADO.NET Data Service服務的元數據,并為服務的實體生成數據類。

為了生成這些代碼,你需要在你的項目(Project)中添加Service Reference,你可以在項目資源管理器(Project Explorer)中Silverlight項目上點擊右鍵,然后選擇‘添加服務引用(即Add Service Reference)’,在彈出的對話框中點擊‘查找(Discover)’按鈕,顯示你項目中的服務(包括ADO.NET Data Service),選擇ADO.NET Data Service端點,點擊確定按鈕。這樣會創建一個新的文件,包含了每個端點對應的data contract類和一個DataServiceContext衍生類,DataServiceContext類用作服務接入點(暴露可查詢的服務端點),這樣會在你的Silverlight項目中包含這些類,并在System.Data.Services.Client.dll(Silverlight 2 SDK的一部分)中添加一個引用。Silverlight客戶端代碼和其它使用.NET的代碼基于LINQ的查詢非常相似,下面是示例代碼:

// 創建服務類指定ADO.NET Data Service的位置
 NorthwindEntities ctx = 
  new NorthwindEntities(new Uri("Products.svc", UriKind.Relative));
//創建LINQ查詢
var qry = from p in ctx.Products
               orderby p.ProductName
                select p;

當你執行這個查詢時,它會直接向目標數據發送一個Web請求,但這里的Silverlight代碼和標準的LINQ查詢不同,在Silverlight中不允許同步Web請求,因此,如果要執行異步,你首先需要將查詢轉換成DataServiceQuery對象,然后再調用BeginExecute啟動異步執行:

// 創建一個DataServiceQuery,因為查詢返回的是Products
DataServiceQuery productQuery =
  (DataServiceQuery)qry;
//指定一個callback函數執行異步查詢
  productQuery.BeginExecute(new 
    AsyncCallback(OnLoadComplete),
    productQuery);

當這些查詢執行完后,無論操作是否成功,在AsyncCallback中指定的方法都會執行,通常你會在AsyncCallback中包含原始查詢,因此可以在callback方法中檢索它,你也可以將其保存為類的一部分,正如你在例3中看到的:

例3 將結果添加到集合中

void OnLoadComplete(IAsyncResult result)
{
  //為查詢獲取一個引用
  DataServiceQuery productQuery =
    (DataServiceQuery)result.AsyncState;
 
  try
  {
    //獲得結果并將其添加到集合中
    List products = productQuery.EndExecute(result).ToList();
 
  }
  catch (Exception ex)
  {
    if (HtmlPage.IsEnabled)
    {
      HtmlPage.Window.Alert("Failed to retrieve data: " + ex.ToString());
    }
  }
 
}

如果你以前還沒有處理過LINQ,理解這些模型可能就非常困難,在寫本文的時候,除了在異步包中執行LINQ(如ThreadPool和BackgroundWorker)外,還沒有關于異步LINQ很好的模型,Silverlight需要所有的請求都是異步的,因此在使用ADO.NET Data Service客戶端庫時需要使用這個模型。

載入相關實體

ADO.NET Data Service也允許你選擇如何載入相關的實體,在前面的例子中,我是從服務器中載入Products(產品)的,每個產品與供應商都有一個關系。使用前面的LINQ查詢,我們只檢索了產品,如果我還想顯示供應商和分類信息,我們可以按需載入相關信息,也可以在原始查詢中明確地從服務器去檢索,這兩種技術各有各的優勢,但如果你清楚地知道需要顯示哪些信息,明確地載入可能更有效,如果你只想為一些實體載入數據,使用按需檢索可能會更好。

默認情況下,如果你沒有明確地載入屬性,關系屬性(如產品供應商)就是空的,為便于按需載入,DataServiceContext類有一個BeginLoadProperty方法(遵循相同的異步模式)可以指定源實體,屬性名和callback。

public void LoadSupplierAsync(Product theProduct)
{
  TheContext.BeginLoadProperty(theProduct,
                               "Supplier",
                               new AsyncCallback(SupplierLoadComplete),
                               null);
  }

  public void SupplierLoadComplete(IAsyncResult result)
  {
    TheContext.EndLoadProperty(result);
  }

調用EndLoadProperty后,屬性和相關的實體就被正確地載入,在許多情況下,你可能想在原始查詢中明確地載入它們,因為如此,LINQ提供者支持Expand擴展方法,這個方法允許你指定屬性的名稱路徑便于查詢執行時載入它們,Expand方法在LINQ查詢的from子句中使用,它告訴提供者視圖載入這些相關實體,例如,如果你使用Expand方法改變了Category 和 Supplier原始查詢,在原始查詢執行期間,我們的對象將會載入這些相關實體:

var qry =
  from p in TheContext.Products.Expand("Supplier").Expand("Category")
          orderby p.ProductName
          select p;

如果你使用ADO.NET Data Service讀取數據,知道如何創建一個查詢,運行它,載入你想要的相關實體。如果你需要真實地修改數據,只需要將你的新數據綁定到你的Silverlight控制器即可。

#p#

變化管理

ADO.NET Data Service客戶端庫不支持對象的自動變更監視,這意味著當對象,集合和關系發生變化時,需要開發人員告訴DataServiceContext這些變化,通知DataServiceContext對象的API相當簡單,如例4所示:

例4 DataServiceContext變更API

方法 描述
AddObject 添加一個新創建的對象
UpdateObject 標記一個已經變化的對象
DeleteObject 標記一個刪除的對象
AddLink 在兩個對象之間添加一個鏈接
UpdateLink 更新兩個對象之間的鏈接
DeleteLink 刪除兩個對象之間的鏈接

這意味著你要監視對象的變化,并在你自己的代碼中通知DataServiceContext對象,表面上看起來這樣讓人很失望,因為沒有實現自動化的變化管理,但這樣可以讓庫變得更有效也更mini。

你可能會對如何監視對象的變化感到奇怪,答案就是生成的代碼中,在每個生成的data contract類中,當類中的數據變化時partial方法被調用,如果這些方法從來沒有使用過,它們本身不會造成任何資源消耗,你可以在任何支持變化通知的data contracts上使用partial方法機制,只需要在partial方法中調用DataServiceContract即可,不用連接DataServiceContract整個類。

幸運的是,Silverlight已經有一個接口支持變化通知了(INotifyPropertyChange),通過這個接口可以在你的實現中將任何變化通知給感興趣的人,例如你可以在你的data contract類(在我們的例子中是Product類)中調用InotifyPropertyChange定義一個事件,當數據發生變化時可以激活它,下面就是具體的示例:

public partial class Product : INotifyPropertyChanged
{
  public event PropertyChangedEventHandler PropertyChanged;
}

這樣當任何屬性發生變化時都可以觸發一個事件,你可以通過partial方法決定什么時候觸發這個事件,例如,當ProductName發生變化時要通知預定人,只需要調用OnProductNameChanged方法,然后觸發PropertyChanged事件,傳遞ProductName通知變化的屬性給事件預定人,下面是代碼:

partial void OnProductNameChanged()
{
  if (PropertyChanged != null)
  {
    PropertyChanged(this, new PropertyChangedEventArgs("ProductName"));
  } 
}

通過在這些可寫的屬性上調用這些partial方法,監視你對象的變化就很簡單了,當對象發生變化時,你可以注冊PropertyChanged事件然后通知DataServiceContext對象:

//在OnLoadComplete方法中,獲取結果然后將它們添加到集合中
List products = productQuery.EndExecute(result).ToList();
foreach (Product product in products)
{
  //觸發變化通知
  product.PropertyChanged +=
    new PropertyChangedEventHandler(product_PropertyChanged);
}

 

最后你可以調用product_PropertyChanged方法通知DataServiceContext對象:

void product_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
  Product product = (Product)sender;
  TheContext.UpdateObject(product);
}

同樣,在創建對象或刪除對象時也需要通知DataServiceContext,如:

void addNewButton_Click(object sender, RoutedEventArgs e)
{
  Product theProduct = new Product();
  // ...
  TheContext.AddObject(theProduct);
}
 
void deleteButton_Click(object sender, RoutedEventArgs e)
{
  Product theProduct = (Product)theList.SelectItem;
  TheContext.DeleteObject(theProduct);
  theCollection.Remove(theProduct);
}

在這些代碼中,你可以在你的Silverlight UI中修改這些對象,讓數據綁定和變化通知代碼確保讓DataServiceContext知道所有變化都會引發什么后果,但你如何對這些服務執行真實的更新呢?

通過服務更新

現在你的DataServiceContext對象已經知道數據的變化,但還需要一個方法通知給服務器,為了解決這個問題,DataServiceContext類提供了一個BeginSaveChanges方法,它和本文前面描述的查詢都使用了相同的異步方法,BeginSaveChanges方法將所有變化都吸收進DataServiceContext,并將它們發送給服務器:

TheContext.BeginSaveChanges(SaveChangesOptions.None,

new AsyncCallback(OnSaveAllComplete),

null);

調用BeginSaveChanges時,有一個標志枚舉調用SaveChangesOptions,這個枚舉允許你指定兩個選項:是否使用批處理,是否繼續,即使某些變化保存失敗。通常,我建議使用批處理,實際上,在某些父/子關系類型上批處理是必須的,因為父子之間可能使用了引用完整性約束,這樣更新才能保證父子之間的一致性。

保存完畢時,將會執行callback,有兩個機制可以傳播錯誤消息給你,首先,如果在執行保存時出現了異常,當你在調用EndSaveChanges時,會拋出異常,因為如此,你可能想要使用try/catch來捕獲災難性的錯誤;另外,EndSaveChanges返回的類型是一個DataServiceResponse對象,DataServiceResponse有一個HasErrors屬性,但在Silverlight 2 Beta 2版本庫中它還不夠安全:

void OnSaveAllComplete(IAsyncResult result)
{
  bool succeeded = true;
  try
  {
    DataServiceResponse response = 
      (DataServiceResponse)TheContext.EndSaveChanges(result);
 
    foreach (OperationResponse opResponse in response)
    {
      if (opResponse.HasErrors)
      {
        succeeded = false;
      }
    }
 
  }
  catch (Exception ex)
  {
    succeeded = false;
  }
 
  // Alert the User
}

你可以重復使用OperationResponse對象來查看是否出現了錯誤,DataServiceResponse是OperationResponse對象的一個集合,在以后的版本中,你應該可以依賴于DataServiceResponse類自身的HasErrors屬性了。

服務調式

在調試服務時,你要執行三個重要的任務:查看DataServiceContext對象中數據的狀態,查看ADO.NET Data Services產生的請求,以及捕獲服務器錯誤。

首先我們處理DataServiceContext對象中的實體狀態,DataServiceContext類暴露了兩個有用的集合:Entities和Links,這些集合是只讀的,由DataServiceContext進行跟蹤,在調式時,不管你是將對象標記為已變化還是未變化,在調試器中查看這些集合是非常有用的,可以幫助你確定跟蹤思路是不是正確的。

注意對你而言,查看你的Silverlight 2程序對服務器的真實請求也是很重要的,最好的方法是使用網絡代理,我個人使用的是Fiddler2,如果你對Fiddler2不熟悉,也可以使用Web traffic之類的工具來捕獲數據包,查看真正發生了什么。

對于ADO.NET Data Service而言,你可能想查看你在線上傳來傳去的都是什么,即Silverlight程序發出的數據和接收到的數據,可以去我的博客(http://wildermuth.com/2008/06/07/Debugging_ADO_NET_Data_Services_with_Fiddler)轉轉。

最后,.NET Framework 3.5 SP1不會將服務端錯誤傳遞給客戶端了,實際上,服務器上的大部分錯誤都是服務器吞下去的,調試服務端錯誤的最好辦法是在調試菜單(Debug->Exceptions…)中使用Exception選項,配置調試器停止一切.NET異常,如果你選擇了這個選項,你可以通過服務看到拋出的異常。

我在本文的目標是展示ADO.NET Data Service是如何在Silverlight 2和基于服務的模塊之間建立起連接的,現在你應該已經知道如何使用ADO.NET Data Service從服務器讀取數據和往服務器寫數據了,再也不用自己動手設計Web Service了,正如你所看到的,Silverlight、ADO.NET Data Service和LINQ三者的組合讓你可以創建強大的基于數據驅動的Web應用程序,具有Web 2.0技術的所有有點。

 

【編輯推薦】

  1. LINQ to SQL實現數據訪問通用基類
  2. SQL連接中加條件查詢的LINQ表達式寫法
  3. 圖解Silverlight 3的7個新功能
責任編輯:彭凡 來源: 51CTO
相關推薦

2009-08-13 11:22:59

LINQ和ADO.NE

2009-09-14 13:37:25

LINQ ADO.NE

2009-12-29 16:12:25

ADO程序員

2009-12-28 15:11:36

ADO.NET專家

2009-12-25 10:25:59

2009-12-29 14:09:17

ADO.NET通用接口

2009-12-24 14:06:22

ADO.NET 應用程

2009-12-24 15:18:42

創建ADO.NET

2009-11-12 13:26:56

使用ADO.NET參數

2009-12-21 17:35:24

ADO.NET對象

2009-12-23 17:30:54

ADO.NET應用程序

2009-12-21 16:45:41

ADO.NET程序

2009-11-13 09:45:54

ADO.NET程序集

2009-12-25 17:05:32

ADO.NET數據庫

2009-12-22 15:03:51

ADO.NET使用

2011-05-20 17:05:59

ADO.NET

2009-12-21 17:23:56

ADO.Net程序

2009-12-24 14:45:32

ADO.NET程序

2024-06-18 13:17:02

數據庫框架

2009-12-21 16:53:06

ADO.NET使用說明
點贊
收藏

51CTO技術棧公眾號

国产精选一区二区| 欧美黑人巨大精品一区二区| 8x8x最新地址| 污污的网站在线免费观看| 成人h精品动漫一区二区三区| 国产91精品网站| 丝袜 亚洲 另类 欧美 重口| 亚洲激情播播| 欧美精品乱码久久久久久按摩| 欧美久久在线观看| 日本在线看片免费人成视1000| 成人深夜视频在线观看| 国产精品美女在线观看| 国产无套内射又大又猛又粗又爽| 成人精品电影| 日韩精品一二三四区| 欧美性猛交乱大交| 成人午夜毛片| 精品久久久中文| 400部精品国偷自产在线观看 | jizz欧美| 午夜精品视频在线观看| 青少年xxxxx性开放hg| 激情在线视频| 北条麻妃一区二区三区| 91视频国产高清| 亚洲精品无码久久久久| 国产一区二区三区的电影| 麻豆国产va免费精品高清在线| 亚洲综合网在线观看| 成人爽a毛片免费啪啪红桃视频| 欧美日韩一级二级三级| 国产一区视频免费观看| av中文在线资源库| 亚洲一区国产视频| 一级黄色免费在线观看| www.亚洲资源| 国产拍揄自揄精品视频麻豆| 久久资源av| 天天操天天操天天操| 国产成人精品免费看| 亚洲一区二区三区视频| 一级黄色片免费| 久久99国产精品尤物| 国产精品露脸自拍| 国产成人自拍偷拍| 日韩中文字幕区一区有砖一区 | 欧美性受黑人性爽| 欧美一区二区三区| 亚洲欧美怡红院| 伊人久久大香线蕉av一区| avtt在线播放| 国产精品国产三级国产普通话99 | 永久免费看mv网站入口| 99久久久国产精品美女| 沈樵精品国产成av片| 欧美日韩色婷婷| 欧美 日韩 激情| 欲香欲色天天天综合和网| 狠狠躁天天躁日日躁欧美| 免费无遮挡无码永久视频| 欧美激情20| 欧美性猛交xxxx乱大交3| 国产精品97在线| 精品123区| 欧美日韩小视频| 在线a免费观看| 午夜电影一区| 亚洲精品v天堂中文字幕| 欧美丰满少妇人妻精品| 精品视频黄色| 久久九九精品99国产精品| 欧美另类视频在线观看| 亚洲精品1区2区| 日产精品久久久一区二区福利| 亚洲 国产 日韩 欧美| 精品中文av资源站在线观看| 97人人模人人爽视频一区二区| 亚洲第九十九页| 99精品国产热久久91蜜凸| 欧美日韩一区二区视频在线| 亚洲1卡2卡3卡4卡乱码精品| 亚洲尤物视频在线| av观看免费在线| 青青草国产一区二区三区| 日韩精品一区二区三区视频播放| 影音先锋人妻啪啪av资源网站| 你懂的视频欧美| 久久这里有精品| 日韩欧美亚洲视频| 久久精品国产第一区二区三区| 5566中文字幕一区二区| 欧美日韩在线精品一区二区三区激情综| 国产欧美精品区一区二区三区| 久久av高潮av| 桃花岛成人影院| 日韩精品中文字幕一区二区三区 | 国产美女www爽爽爽视频| 国产69精品久久久久毛片| 日本一区二区三区在线视频| 伊人电影在线观看| 色爱区综合激月婷婷| 蜜桃视频无码区在线观看| 国内精品久久久久久久久电影网| 免费97视频在线精品国自产拍| 51国产偷自视频区视频| 国产麻豆成人精品| 日韩区国产区| 国产传媒在线观看| 91精品国产高清一区二区三区蜜臀 | 亚洲精品欧美精品| 91九色国产在线播放| 7777精品久久久大香线蕉 | 中文字幕日韩精品一区| 成年人午夜视频在线观看| 高清国产一区二区三区四区五区| 亚洲片在线资源| 国产一级二级三级视频| 蜜臀va亚洲va欧美va天堂| 久久精品99| 日韩影视在线| 欧美精品xxxxbbbb| 国产三级黄色片| 久久免费国产| 久久99久久99精品蜜柚传媒| 麻豆蜜桃在线| 日韩一区二区三区视频在线观看| 91导航在线观看| 美女视频一区免费观看| 久久草.com| 欧美xxxx视频| 日韩欧美视频一区| 男的操女的网站| 国产麻豆成人传媒免费观看| 亚洲资源在线网| 欧美日韩五区| 亚洲欧洲自拍偷拍| 国产熟妇一区二区三区四区| 91免费国产视频网站| 自拍日韩亚洲一区在线| 粉嫩av一区二区| 欧美激情伊人电影| www五月婷婷| 亚洲国产精品欧美一二99| wwwww在线观看| 亚洲性感美女99在线| 成人av片网址| 国产在线美女| 亚洲美女又黄又爽在线观看| 久久国产视频一区| 久久精品欧美一区二区三区不卡| 别急慢慢来1978如如2| 精品国产99| 国产裸体写真av一区二区 | 久久久久一本一区二区青青蜜月| www视频在线| 精品国产91乱高清在线观看| 麻豆精品免费视频| 青青草97国产精品免费观看无弹窗版| 亚洲精品一区二区三区蜜桃久| 国产精品伊人| 色与欲影视天天看综合网| 欧美在线 | 亚洲| 欧美日韩色婷婷| 日本理论中文字幕| 国精品**一区二区三区在线蜜桃| 欧美xxxx吸乳| 高清一区二区三区| 国产精品18久久久久久麻辣| 国产免费a∨片在线观看不卡| 欧美日韩一区国产| 一区二区视频免费看| 99久久精品一区二区| 情侣黄网站免费看| 久久久久蜜桃| 精品视频一区二区三区四区| 日韩中文视频| 欧美成人一区二区三区电影| 三级毛片在线免费看| 色天使色偷偷av一区二区| 五月婷婷综合激情网| 国产成都精品91一区二区三 | 精品一二线国产| 国产xxxx振车| 免费欧美一区| 3d蒂法精品啪啪一区二区免费| 最近高清中文在线字幕在线观看1| 在线电影中文日韩| 亚洲精品喷潮一区二区三区| 色偷偷久久人人79超碰人人澡 | 欧美视频13p| 黄色裸体一级片| 99这里只有精品| 国产3p在线播放| 亚洲综合日韩| 免费看污污视频| 精品日产免费二区日产免费二区| 亚洲最大的成人网| 欧美7777| 国内精品久久久久久久久| a√在线中文网新版址在线| 欧美精品一区在线观看| 一炮成瘾1v1高h| 欧美性高潮在线| 黄色一级视频免费| 国产精品美日韩| 疯狂揉花蒂控制高潮h| 国产呦精品一区二区三区网站| 黄色影院一级片| 欧美激情精品久久久六区热门| 日韩精品av一区二区三区| 国产精品网站在线看| 91丨九色丨国产在线| 精品成人av| 91精品国产亚洲| 欧美男男video| 精品国产一区二区三区久久狼5月| 日韩有码电影| 亚洲黄一区二区| www.国产麻豆| 日韩一区二区中文字幕| 伊人网综合在线| 欧美专区日韩专区| 欧美日韩乱国产| 亚洲成av人影院在线观看网| 唐朝av高清盛宴| 综合分类小说区另类春色亚洲小说欧美| 成年人免费观看视频网站| 99久久久国产精品| 日本一级片在线播放| 国产suv精品一区二区883| 91pony九色| 国内精品伊人久久久久av一坑 | 国产小视频国产精品| 午夜视频免费看| 亚洲国产小视频| 性xxxx视频| 亚洲黄色av女优在线观看| 天天操天天干天天插| 亚洲第一页在线| 搡老岳熟女国产熟妇| 精品福利av导航| 国产 日韩 欧美 精品| 亚洲国产成人精品电影| 日韩有码第一页| 亚洲国产91精品在线观看| 乱精品一区字幕二区| 亚洲变态欧美另类捆绑| 手机在线观看免费av| 亚洲精品久久久久久久久久久久久| 欧美在线 | 亚洲| 亚洲国产欧美一区二区丝袜黑人| 手机av免费在线观看| 精品无人国产偷自产在线| 日韩大胆人体| 一本色道久久综合亚洲精品小说| 福利视频在线看| 日韩视频在线免费观看| 免费av网站在线看| 欧美不卡视频一区发布| 婷婷色在线播放| 97在线观看视频国产| 日韩欧美一中文字暮专区| 国产精品6699| 成人在线啊v| 成人自拍网站| 蜜桃精品wwwmitaows| 亚洲巨乳在线观看| 欧美精品大片| www.四虎成人| 精品一区二区三区av| 四虎精品一区二区| 久久精品一二三| av激情在线观看| 午夜成人在线视频| 超碰在线免费97| 日韩欧美成人一区二区| 完全免费av在线播放| 手机av免费观看| 欧美一区二区视频在线观看2022| 日本高清视频在线| 中文字幕日韩欧美在线| 黄色成人在线网| 国产精品露脸av在线| 哺乳一区二区三区中文视频| 欧美日本韩国一区二区三区| 亚洲第一天堂| 黑森林福利视频导航| 韩国v欧美v亚洲v日本v| 亚洲熟妇一区二区三区| 亚洲乱码一区二区三区在线观看| 久久久久久久久影院| 337p亚洲精品色噜噜噜| 青青色在线视频| 精品综合久久久久久97| 日韩一区精品| 国产日韩在线一区二区三区| 久久精品国产68国产精品亚洲| 国产无限制自拍| 国产自产2019最新不卡| a毛片毛片av永久免费| 亚洲国产精品久久久男人的天堂| 中日精品一色哟哟| 日韩成人激情在线| 羞羞网站在线免费观看| 国产精品第10页| 日韩av午夜| 国产精品一区在线免费观看| 日韩成人精品在线观看| 中文在线一区二区三区| 亚洲伦在线观看| 国产精品毛片久久久久久久av| 精品亚洲一区二区| 欧美人与禽猛交乱配| 成人网在线免费看| 欧美日韩在线观看视频小说| 又粗又黑又大的吊av| 成人性色生活片| 欧美日韩精品亚洲精品| 欧美精品日韩综合在线| 香蕉视频国产在线观看| 日本精品一区二区三区在线播放视频| 中文字幕视频精品一区二区三区| 中文字幕一区二区三区四区五区六区| 视频一区国产视频| 毛片网站免费观看| 黄色成人在线免费| 人妻视频一区二区三区| 欧美日本黄视频| 欧美欧美在线| 日韩中文字幕在线不卡| 国产一区视频导航| 最新一区二区三区| 91精品国产日韩91久久久久久| 麻豆网站在线看| 91久久嫩草影院一区二区| 爽成人777777婷婷| 污网站在线免费| 1024成人网色www| 国产精品乱码一区二区| 欧美精品中文字幕一区| 视频在线观看免费影院欧美meiju 视频一区中文字幕精品 | 一区二区三区在线视频观看58 | 懂色av一区二区三区免费看| 国产大学生自拍| 精品久久久久香蕉网| h片在线观看| 久久精品99久久| 日韩成人av影视| 操她视频在线观看| 欧美一卡二卡三卡四卡| 国产在线更新| 成人动漫在线视频| 99综合在线| 中文字幕人妻一区二区| 欧美最猛性xxxxx直播| 日本天堂在线观看| 亚洲影院污污.| 在线成人欧美| jizz中文字幕| 91麻豆精品国产91久久久使用方法 | 久久综合在线观看| 一区二区三区波多野结衣在线观看| 黄色a在线观看| 日产日韩在线亚洲欧美| 久久综合99| 乱码一区二区三区| 一本一道久久a久久精品| 91.xxx.高清在线| 99在线首页视频| 六月丁香综合| 免费三级在线观看| 精品电影一区二区三区| 久久精品女人天堂av免费观看| av不卡在线免费观看| 成人免费毛片app| 青娱乐在线免费视频| 蜜臀久久99精品久久久无需会员| 欧美精品中文字幕亚洲专区| 成人午夜激情av| 亚洲愉拍自拍另类高清精品| 伦理片一区二区三区| 91色在线视频| 亚洲欧美卡通另类91av| 91狠狠综合久久久| 亚洲黄色成人网| 国产精品一区二区精品| 免费欧美一级视频| 自拍偷拍亚洲激情| 嫩草研究院在线| 97在线中文字幕| 日本中文一区二区三区| 国产无遮挡又黄又爽| 在线视频日韩精品| 日韩欧美中文字幕电影| 亚洲精品在线视频播放| 色妞www精品视频| 国产精品—色呦呦| 中文字幕一区二区中文字幕 | 精品国产免费一区二区三区香蕉|