激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語(yǔ)言|JavaScript|易語(yǔ)言|vb.net|

服務(wù)器之家 - 編程語(yǔ)言 - ASP.NET教程 - EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

2020-05-17 14:52Jeffcky ASP.NET教程

這篇文章主要給大家介紹了關(guān)于EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。

前言

自從項(xiàng)目上了.NET Core平臺(tái)用上了EntityFramework Core就再?zèng)]碰過(guò)EntityFramework 6.x版本,目前而言EntityFramework 6.x是用的最多,無(wú)論是找工作而言還是提升自身技術(shù)而言皆自身收益,同時(shí)呢,大多數(shù)時(shí)間除了工作之外,還留有一小部分時(shí)間在寫(xiě)EntityFramework 6.x和EntityFramework Core的書(shū)籍,所以將EntityFramework 6.x相當(dāng)于是從零學(xué)起,EntityFramework 6.x又添加了許多特性,所以花了一些時(shí)間去看并整理了下來(lái),本節(jié)相當(dāng)于是自己一直未碰到過(guò)的問(wèn)題,于是花了一點(diǎn)時(shí)間在多個(gè)上下文遷移到不同數(shù)據(jù)庫(kù)并實(shí)現(xiàn)分布式事務(wù)上,作為基礎(chǔ)入口且同步于書(shū)籍,供閱讀者學(xué)習(xí)也是我的點(diǎn)滴積累,文章如有錯(cuò)誤,請(qǐng)指正。

模型建立

在開(kāi)始EntityFramework 6.x內(nèi)容敘述之前,我們還是老套路,首先準(zhǔn)備模型,我們搞一個(gè)預(yù)約航班的基本模型,一個(gè)是航班實(shí)體,另外一個(gè)為預(yù)約實(shí)體,請(qǐng)看如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/// <summary>
 /// 航班
 /// </summary>
 public class FlightBooking
 {
  /// <summary>
  /// 航班Id
  /// </summary>
  public int FlightId { get; set; }
 
  /// <summary>
  /// 航班名稱
  /// </summary>
  public string FilghtName { get; set; }
 
  /// <summary>
  /// 航班號(hào)
  /// </summary>
  public string Number { get; set; }
 
  /// <summary>
  /// 出行日期
  /// </summary>
  public DateTime TravellingDate { get; set; }
 }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/// <summary>
 /// 預(yù)訂
 /// </summary>
 public class Reservation
 {
  /// <summary>
  /// 預(yù)訂Id
  /// </summary>
  public int BookingId { get; set; }
 
  /// <summary>
  /// 預(yù)訂人
  /// </summary>
  public string Name { get; set; }
 
  /// <summary>
  /// 預(yù)訂日期
  /// </summary>
  public DateTime BookingDate { get; set; } = DateTime.Now;
 }
?
1
2
3
4
5
public class TripReservation
 {
  public FlightBooking Filght { get; set; }
  public Reservation Hotel { get; set; }
 }

此類用于維護(hù)航班和預(yù)約的實(shí)體,在創(chuàng)建預(yù)約航班時(shí)使用。在EntityFramework 6.0+版本上出現(xiàn)了基于代碼配置(Code-based Configuration),對(duì)于數(shù)據(jù)庫(kù)初始化策略和其他等等配置,我們單獨(dú)建立一個(gè)配置類來(lái)維護(hù),而無(wú)需如我們以往一樣放在DbContext上下文派生類構(gòu)造函數(shù)中,這樣一來(lái)上下文派生類看起來(lái)則潔凈很多。

?
1
2
3
4
5
6
7
8
public class HotelFlightConfiguration : DbConfiguration
 {
  public HotelFlightConfiguration()
  {  
   SetDatabaseInitializer(new DropCreateDatabaseIfModelChanges<HotelDBContext>());
   SetDatabaseInitializer(new DropCreateDatabaseIfModelChanges<FlightDBContext>());
  }
 }

接下來(lái)我們?cè)賮?lái)配置兩個(gè)DbContext上下文派生類即HotelDbContext和FlightDbContext,并且基本配置信息利用特性來(lái)修飾,如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[DbConfigurationType(typeof(HotelFlightConfiguration))]
 public class FlightDBContext : DbContext
 {
  public FlightDBContext() : base("name=flightConnection")
  { }
 
  public DbSet<FlightBooking> FlightBookings { get; set; }
 
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
   modelBuilder.Configurations.Add(new FlightBookingMap());
   base.OnModelCreating(modelBuilder);
  }
 }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[DbConfigurationType(typeof(HotelFlightConfiguration))]
 public class HotelDBContext: DbContext
 {
  public HotelDBContext():base("name=reservationConnction")
  { }
 
  public DbSet<Reservation> Reservations { get; set; }
 
  protected override void OnModelCreating(DbModelBuilder modelBuilder)
  {
   modelBuilder.Configurations.Add(new ReservationMap());
   base.OnModelCreating(modelBuilder);
  }
 }

對(duì)應(yīng)的映射配置已經(jīng)敘述很多次了,我們不用廢話,直接給出。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class FlightBookingMap : EntityTypeConfiguration<FlightBooking>
 {
  public FlightBookingMap()
  {
   //table
   ToTable("FlightBookings");
 
   //key
   HasKey(k => k.FlightId);
 
   //property
   Property(p => p.FilghtName).HasMaxLength(50);
   Property(p => p.Number);
   Property(p => p.TravellingDate);
  }
 }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class ReservationMap : EntityTypeConfiguration<Reservation>
 {
  public ReservationMap()
  {
   //table
   ToTable("Reservations");
 
   //key
   HasKey(k => k.BookingId);
 
   //property
   Property(p => p.BookingId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
   Property(p => p.Name).HasMaxLength(20);
   Property(p => p.BookingDate);
  }
 }

如上兩個(gè)上下文我們將遷移到不同數(shù)據(jù)庫(kù),所以連接字符串當(dāng)然是兩個(gè)啦。

?
1
2
3
4
<connectionStrings>
 <add name="reservationConnction" connectionString="Data Source=WANGPENG;Initial Catalog=ReservationDb;Integrated Security=true" providerName="System.Data.SqlClient" />
 <add name="flightConnection" connectionString="Data Source=WANGPENG;Initial Catalog=FlightDb;Integrated Security=true" providerName="System.Data.SqlClient" />
 </connectionStrings>

好了,模型和上下文一切都已構(gòu)建完畢,接下來(lái)進(jìn)入到遷移,請(qǐng)往下看。

多個(gè)上下文遷移

一個(gè)上下文進(jìn)行遷移已經(jīng)沒(méi)有什么可說(shuō)的了,在大多數(shù)場(chǎng)景下,貌似都是一個(gè)應(yīng)用程序中僅僅存在一個(gè)上下文,因?yàn)槟缓髮?duì)應(yīng)的只有一個(gè)數(shù)據(jù)庫(kù),這個(gè)大家是手到擒來(lái),而對(duì)于多個(gè)上下文遷移對(duì)應(yīng)不同數(shù)據(jù)庫(kù)遷移又怎么去操作呢?如果你非常熟悉遷移命令,那么就當(dāng)做是回顧吧,如若不然,可以此作為基本參考,有點(diǎn)啰嗦了哈,我們進(jìn)入正文。將模型遷移至數(shù)據(jù)庫(kù)并持久化只需要如下三步。

多個(gè)上下文遷移至不同文件夾目錄

Enable-Migrations命令

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

Add-Migration命令

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

Update-database命令

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

當(dāng)統(tǒng)一應(yīng)用程序只存在一個(gè)上下文時(shí),我們只需要Enabel-Migrations即可,但是若存在多個(gè)上下文,若不明確指定上下文很顯然會(huì)遷移報(bào)錯(cuò),首先我們?cè)贜uGet控制臺(tái)將項(xiàng)目更換到上下文所在項(xiàng)目中。

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

接下來(lái)運(yùn)行Enable-Migrations初始化遷移目錄,很明顯會(huì)出現(xiàn)遷移異常。

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

由于存在多個(gè)上下文,所以我們需要明確指定遷移哪個(gè)上下文。通過(guò)在其命令后繼續(xù)添加-ContextTypeName指定上下文,并繼續(xù)利用-MigrtionsDirectory指定遷移目錄,最后則是如下命令(不知道有哪些命令嗎,在每個(gè)命令后添加一個(gè)【-】橫桿并按下Tab鍵則出現(xiàn)你想要的命令)。

Enable-Migrations -ContextTypeName FlightDbContext -MigrationsDirectory:FlightMigrations

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

接下來(lái)利用Add-Migration命令對(duì)已掛起模型改變搭建基架,也就是說(shuō)將上次遷移后我們對(duì)模型發(fā)生了更改,以此為下一次遷移搭建基架,此時(shí)生成的模型狀態(tài)為掛起狀態(tài)或者稱作為待定狀態(tài)。我們需要遷移上述生成FlightMigrations目錄下的Configuration類,所以此時(shí)在Add-Migration命令后指定-ConfigurationTypeName,然后通過(guò)-Name指定第一次基架名稱。

Add-Migration -ConfigurationTypeName EntityFrameworkTransactionScope.Data.FlightMigrations.Configuration -Name Initial

或者

Add-Migration -ConfigurationTypeName EntityFrameworkTransactionScope.Data.FlightMigrations.Configuration "Initial"

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

最后則只需要通過(guò)Update-database來(lái)持久化到數(shù)據(jù)庫(kù)生成表了。

Update-Database -ConfigurationTypeName EntityFrameworkTransactionScope.Data.FlightMigrations.Configuration

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

同理我們對(duì)HotelDbContext利用上述三步命令來(lái)進(jìn)行遷移,最后我們能夠很清晰的看到,每個(gè)上下文遷移在不同目錄,如下:

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

上述遷移也沒(méi)任何毛病,將每個(gè)上下文單獨(dú)遷移生成文件夾,那么我們是否有想過(guò)將多個(gè)上下文遷移到同一目錄文件夾下且區(qū)分開(kāi)來(lái)呢,在我們只有一個(gè)上下文時(shí)默認(rèn)給我們創(chuàng)建的文件夾為Migrations,我們就在Migrtions文件夾下生成不同上下文遷移配置。

多個(gè)上下文遷移至相同文件夾目錄

這個(gè)其實(shí)也很簡(jiǎn)單,我們?cè)?MigrationDirectoty后面可以直接指定某個(gè)文件夾生成上下文,例如C:\A\DbContext,EntityFramework也做到了這點(diǎn),下面我們來(lái)看看。

Enable-Migrations -ContextTypeName FlightDbContext -MigrationsDirectory Migrations\FlightDbContext

Enable-Migrations -ContextTypeName HotelDbContext -MigrationsDirectory Migrations\HotelDbContext

其余兩步運(yùn)行方式和遷移不同一樣,最終我們會(huì)看到想要的結(jié)果。

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

通過(guò)上述遷移最終將生成FlightDb和ReservationDb兩個(gè)數(shù)據(jù)庫(kù)并對(duì)應(yīng)FlightBookings和Reservations表。好了到此關(guān)于多個(gè)上下文遷移兩種方式就結(jié)束了,我們繼續(xù)本節(jié)的話題。

分布式事務(wù)

有時(shí)候我們需要跨數(shù)據(jù)庫(kù)管理事務(wù),例如有這樣一個(gè)場(chǎng)景,有兩個(gè)數(shù)據(jù)庫(kù)db1和db2,而tb1在db1中,tb2在db2中,同時(shí)tb1和tb2是關(guān)聯(lián)的,在上述中我們創(chuàng)建的航班和預(yù)訂模型,我們需要同時(shí)插入航班數(shù)據(jù)和預(yù)約數(shù)據(jù)到不同數(shù)據(jù)庫(kù)中,此時(shí)則要求事務(wù)一致性,所以為了處理這樣的要求,在.NET 2.0,在System.Transaction命名空間下為我們提供了TransactionScope類。 此類提供了一種使代碼塊參與事務(wù)而不需要與事務(wù)本身交互的簡(jiǎn)單方式。強(qiáng)烈建議在using塊中創(chuàng)建TransactionScope對(duì)象。

當(dāng)TransactionScope被實(shí)例化時(shí),事務(wù)管理器需要確定要參與哪個(gè)事務(wù)。一旦確定,該實(shí)例將一直參與到事務(wù)中。 在創(chuàng)建TransactionScope對(duì)象時(shí),我們需要傳遞具有以下值的TransactionScopeOption枚舉:

  • Required:實(shí)例必須需要事務(wù),如果事務(wù)已存在,則使用已存在事務(wù),否則將創(chuàng)建新事務(wù)。
  • RequiresNew:始終為實(shí)例創(chuàng)建一個(gè)新的事務(wù)。
  • Suppress:創(chuàng)建實(shí)例時(shí),其他已存在事務(wù)將被抑制,因?yàn)樵搶?shí)例內(nèi)的所有操作的完成而無(wú)需其他已存在事務(wù)。

接下來(lái)我們利用上述枚舉中第二種方式來(lái)實(shí)現(xiàn)航班預(yù)約,簡(jiǎn)單邏輯如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public class MakeReservation
 {
 
  FlightDBContext flight;
 
  HotelDBContext hotel;
 
  public MakeReservation()
  {
   flight = new FlightDBContext();
   hotel = new HotelDBContext();
  }
 
  //處理事務(wù)方法
  public bool ReservTrip(TripReservation trip)
  {
   bool reserved = false;
 
   //綁定處理事務(wù)范圍
   using (var scope = new TransactionScope(TransactionScopeOption.RequiresNew))
   {
    try
    {
     //航班信息
     flight.FlightBookings.Add(trip.Filght);
     flight.SaveChanges();
 
     //預(yù)約信息
     hotel.Reservations.Add(trip.Hotel);
     hotel.SaveChanges();
 
     reserved = true;
 
     //完成事務(wù)并提交
     scope.Complete();
    }
    catch (Exception ex)
    {
     throw ex;
    }
   }
   return reserved;
  }
 }

上述ReservTrip方法接受TripReservation對(duì)象。 該方法定義了TransactionScope,并在事務(wù)的上下文中捆綁了用于Flight和Hotel的Create操作,并將代碼寫(xiě)入try-catch塊中。 如果兩個(gè)實(shí)體的SaveChanges方法成功執(zhí)行,那么事務(wù)將被完成,否則回滾。接下來(lái)進(jìn)行控制器調(diào)用。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class TripController : Controller
 {
  MakeReservation reserv;
 
  public TripController()
  {
   reserv = new MakeReservation();
  }
 
  public ActionResult Index()
  {
   return View();
  }
 
  public ActionResult Create()
  {
   return View(new TripReservation());
  }
 
  [HttpPost]
  public ActionResult Create(TripReservation tripinfo)
  {
   try
   {
    tripinfo.Filght.TravellingDate = DateTime.Now;
    tripinfo.Hotel.BookingDate = DateTime.Now;
    var res = reserv.ReservTrip(tripinfo);
 
    if (!res)
    {
     return View("Error");
    }
   }
   catch (Exception)
   {
    return View("Error");
   }
   return View("Success");
  }
 }

我們添加航班預(yù)約視圖:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
@model EntityFrameworkTransactionScope.Data.Entity.TripReservation
 
@{
 ViewBag.Title = "Create";
}
 
<h2 class="text-center">旅游出行</h2>
@using(Html.BeginForm()){
 
 
<table class="table table-condensed table-striped table-bordered">
 <tr>
  <td>
   <table class="table table-condensed table-striped table-bordered">
    <tr>
     <td colspan="2" class="text-center">
      航班信息
     </td>
    </tr>
    <tr>
     <td>
      航班Id:
     </td>
     <td>
      @Html.EditorFor(m => m.Filght.FlightId)
     </td>
    </tr>
    <tr>
     <td>
      航班名稱:
     </td>
     <td>
      @Html.EditorFor(m => m.Filght.FilghtName)
     </td>
    </tr>
    <tr>
     <td>
      航班號(hào):
     </td>
     <td>
      @Html.EditorFor(m => m.Filght.Number)
     </td>
    </tr>
   </table>
  </td>
  <td>
   <table class="table table-condensed table-striped table-bordered">
    <tr>
     <td colspan="2" class="text-center">
      預(yù)約信息
     </td>
    </tr>
    <tr>
     <td>
      預(yù)約Id:
     </td>
     <td>
      @Html.EditorFor(m => m.Hotel.BookingId)
     </td>
    </tr>
    <tr>
     <td>
      客戶名稱
     </td>
     <td>
      @Html.EditorFor(m => m.Hotel.Name)
     </td>
    </tr>
 
   </table>
  </td>
 </tr>
 <tr>
  <td colspan="2" class="text-center">
   <input type="submit" value="提交預(yù)約" />
  </td>
 </tr>
</table>
 
}

視圖展示UI如下:

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

要運(yùn)行應(yīng)用程序并檢查事務(wù),我們需要使用分布式事務(wù)處理協(xié)調(diào)器(DTC)服務(wù)。 該服務(wù)協(xié)調(diào)更新兩個(gè)或多個(gè)事務(wù)受保護(hù)資源的事務(wù),例如數(shù)據(jù)庫(kù),消息隊(duì)列,文件系統(tǒng)等。首先我們需要確保DTC是否已經(jīng)開(kāi)啟,在服務(wù)中進(jìn)行查看并啟用。

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

接下來(lái)打開(kāi)DTC設(shè)置,請(qǐng)按照下列步驟操作或者直接運(yùn)行【dcomcnfg.exe】一步到位打開(kāi)組件服務(wù)。

  • 打開(kāi)控制面板
  • 找到管理工具
  • 找到組件服務(wù)

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

接下來(lái)我們填寫(xiě)相關(guān)信息來(lái)進(jìn)行航班預(yù)約。

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

如上顯示已經(jīng)預(yù)約成功,我們看看兩個(gè)數(shù)據(jù)庫(kù)中的數(shù)據(jù)是否正確插入。

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

在DTC服務(wù)中,若每次提交未中止則提交數(shù)量將增加1,在我們對(duì)預(yù)約模型進(jìn)行配置時(shí),我們將主鍵未設(shè)置為標(biāo)識(shí)列,所以在我們對(duì)主鍵重復(fù)的情況下再來(lái)看看表中數(shù)據(jù)。我們提交三次而預(yù)約主鍵不重復(fù),在第四次時(shí)主鍵輸入為第三次的主鍵,此時(shí)看看結(jié)果如下:

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

EntityFramework 6.x學(xué)習(xí)之多個(gè)上下文遷移實(shí)現(xiàn)分布式事務(wù)詳解

我們驗(yàn)證leFlightBookings和Reservations表中的數(shù)據(jù),則新添加的記錄將不會(huì)顯示在其中。 這意味著TransactionScope已經(jīng)通過(guò)在單個(gè)范圍中將連接與Flight和Hotel數(shù)據(jù)庫(kù)捆綁在一起來(lái)管理Transaction,并監(jiān)控了Committed和Aborted Transaction。

總結(jié)

正如我們?cè)谑褂肊ntityFramework實(shí)體框架作為概念上的數(shù)據(jù)訪問(wèn)層時(shí),在ASP.NET MVC應(yīng)用程序中看到的那樣,在執(zhí)行多個(gè)數(shù)據(jù)庫(kù)操作以存儲(chǔ)與其相關(guān)的相關(guān)數(shù)據(jù)時(shí),始終建議使用TransactionScope來(lái)管理事務(wù)。

原文鏈接:http://www.cnblogs.com/CreateMyself/p/7579579.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久久青青草 | 亚洲欧美在线视频免费 | 欧美成人高清视频 | 99欧美精品| 国产精品久久久久网站 | 黄色大片大毛片 | 中国av中文字幕 | jizzjizz中国人少妇中文 | 久久精品2019中文字幕 | 动漫孕妇被羞羞视频 | 成人不卡免费视频 | av电影网站在线 | 亚洲啪 | 日本网站在线播放 | 免费看真人a一级毛片 | 九九热九九热 | 久久天堂| 成人精品免费在线观看 | 精品在线视频播放 | 国产无限资源在线观看 | 99999久久久久久 | 久草视频免费 | 久久看免费视频 | 国产精品一区网站 | 亚洲一区中文字幕 | 成年人性视频 | 深夜毛片免费看 | 国产一区二区久久精品 | 久久国产综合视频 | 91高清观看| 亚洲国产高清一区 | 在线天堂中文字幕 | 国产亚洲精品久久久久婷婷瑜伽 | 国产亚洲精品yxsp | 黄色羞羞| 色视频在线观看 | 国产成人精品一区二区三区电影 | 色淫影院 | 一级大片久久 | avlululu| 国产精品wwww|