久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Code First :使用Entity. Framework编程(6) ----转发 收藏

發(fā)布時(shí)間:2023/12/20 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Code First :使用Entity. Framework编程(6) ----转发 收藏 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Chapter6

Controlling Database Location,Creation Process, and Seed Data

第6章

控制數(shù)據(jù)庫位置,創(chuàng)建過程和種子數(shù)據(jù)

In previous chapters you have seen how convention and configuration can be used to affect the model and the resulting database schema. In this chapter you will see how the convention and configuration concept applies to the database that is used by Code First.
You’ll learn how Code First conventions select a database and how you can alter this convention or specify the exact database that your context should use. The topics we cover will help you target other database providers, deploy your application, and perform many other database-related tasks.
You’ll also discover how database initializers can be used to control the database creation process and insert seed data into the database. This can be particularly useful when writing automated scenario tests.

前面我們已經(jīng)提到默認(rèn)規(guī)則和配置可以用于影響模型和數(shù)據(jù)庫構(gòu)架。本章你會(huì)看到如何使用Code First來控制數(shù)據(jù)庫。

你將會(huì)學(xué)到Code First默認(rèn)配置如何選擇數(shù)據(jù)庫,也會(huì)掌握如何修改默認(rèn)規(guī)則或指定上下文使用真正的數(shù)據(jù)庫。我們覆蓋的主題將包括指向其他數(shù)據(jù)庫引擎,部署應(yīng)用程序,執(zhí)行數(shù)據(jù)庫有關(guān)的任何等。

你也可以學(xué)習(xí)到數(shù)據(jù)庫初始化器可以用于控制數(shù)據(jù)庫生成過程,添加種子數(shù)據(jù)到數(shù)據(jù)庫中等。這在進(jìn)行自動(dòng)測試的場景時(shí)特別有用。

Controlling the Database Location
控制數(shù)據(jù)庫位置

So far you have relied on the Code First convention to select which database the application targets. By default, Code First has created the database on localhost\SQLEXPRESS using the fully qualified name of your context class for the database name (i.e.,the namespace plus the class name). There will be times when this won’t be appropriate and you need to override the convention and tell Code First which database to connect to. You can modify or replace the convention used to select a database using Code First connection factories. Alternatively, you can just tell Code First exactly which database to use for a particular context, using the DbContext constructors or your application configuration file.

到目前為止我們都是引用了Code First的默認(rèn)規(guī)則來選擇應(yīng)用程序的數(shù)據(jù)庫目標(biāo)。默認(rèn)情況,Code First會(huì)使用localhost\SQLEXPRESS作為目標(biāo)數(shù)據(jù)庫引擎,并使用context類的全名作為數(shù)據(jù)庫名(即命名空間+類名)。如果不符合要求你需要覆寫默認(rèn)規(guī)則然后告知Code First想要連接到哪個(gè)數(shù)據(jù)庫。你可以Code First的連接工廠來選擇數(shù)據(jù)庫,修改或替換默認(rèn)規(guī)則。可選擇地,你也可以使用DbContext構(gòu)造器或應(yīng)用程序配置文件來告知Code First對(duì)某個(gè)特定的上下文使用指定的數(shù)據(jù)庫。

Code First database creation and initialization works with SQL Azure in the same way that it works with any local database. You can see this in action in “Tutorial: Developing a Windows Azure Data Application Using Code First and SQL Azure”. Vendors have begun modifying their database providers to support Code First as well. Be sure to check for this support before trying to use Code First with one of the third-party providers.

小貼士:Code First可以在SQL Azure上使用與任何本地?cái)?shù)據(jù)庫相同的方法進(jìn)行創(chuàng)建和初始化工作。你可在http://www.windowsazure.com/zh-cn/develop/overview/找到相關(guān)的文章。目前數(shù)據(jù)庫供應(yīng)商正在努力修改他們的產(chǎn)品已提供對(duì)Code First的支持。在使用Code First與第三方數(shù)據(jù)庫引擎工作前一定要檢查是否支持。

Controlling Database Location with a Configuration File
使用配置文件控制數(shù)據(jù)庫位置

The easiest and most definitive way to control the database that your context connects to is via a configuration file. Using the configuration file allows you to bypass all database location–related conventions and specify the exact database you want to use. This approach is particularly useful if you want to change the connection string of your context to point to a production database as you deploy your application.

By default, the connection string that you add to your configuration file should have the same name as your context. The name of the connection string can be either just the type name or the fully qualified type name. In “Controlling Connection String Name with DbContext Constructor” on page 132, you will see how to use a connection string with a name that does not match your context name. Add an App.config file to your BreakAwayConsole application with a BreakAwayContext connection string, as shown in Example 6-1.

控制數(shù)據(jù)庫連接最簡單也最可靠的方法是使用配置文件。配置文件可以幫你繞過所有與數(shù)據(jù)庫位置相關(guān)的約定,并能指定到你想使用的確切數(shù)據(jù)庫。這種方法是非常有用的,如果你想改變你的上下文的連接字符串指向一個(gè)生產(chǎn)數(shù)據(jù)庫,為您部署應(yīng)用程序。

默認(rèn)情況下,您添加到您的配置文件的連接字符串應(yīng)該與context有相同的名稱。連接字符串的名稱可以是類型名稱或完全限定的類型名稱。在后面“使用DbContext構(gòu)造器控制連接字符串名稱”,你會(huì)看到如何讓連接字符串的名稱不匹配上下文的名稱。添加一個(gè)App.config文件到BreakAwayConsole應(yīng)用程序,內(nèi)中包含BreakAwayContext的連接字符串,如例6-1所示。
Example 6-1. Connection string specified in App.config

<?xml version="1.0"?> <configuration><connectionStrings><add name="BreakAwayContext"providerName="System.Data.SqlClient"connectionString="Server=.\SQLEXPRESS;Database=BreakAwayConfigFile;Trusted_Connection=true" /></connectionStrings> </configuration>

For those familiar with creating connection strings when your application uses an EDMX file, notice that this is not an EntityConnection String but simply a database connection string. With Code First, you have no need to reference metadata files or the System.Data.Entity Client namespace.、

小貼士:對(duì)熟悉使用EDMX文件創(chuàng)建連接字符串的人,請(qǐng)注意這不是一個(gè)EntityConnection String 而是一個(gè)簡單的數(shù)據(jù)庫連接字符串。使用Code First,你不需要引用元數(shù)據(jù)文件或System.Data.Entity Client 名稱空間。

Modify the Main method so that it calls the InsertDestination method, as shown in Example 6-2.

修改Main方法,調(diào)用InsertDestination方法,如代碼6-2所示。

Example 6-2. Main method modified to call InsertDestination

static void Main() {InsertDestination(); }

Run the application, and you will notice that a BreakAwayConfigFile database has been created in your local SQL Express instance (Figure 6-1).

運(yùn)行應(yīng)用程序,你會(huì)發(fā)現(xiàn),BreakAwayConfigFile數(shù)據(jù)庫實(shí)例已在您的本地SQL Express上創(chuàng)建了(圖6-1)。

Code First matched the BreakAwayContext name of your context with the BreakAwayContext connection string in the configuration file. Because an entry was found in the configuration file, the convention for locating a database was not used. The connection string entry could also have been named DataAccess.BreakAwayContext, which is the fully qualified name of the context.
Code First使用配置文件中的BreakAwayContext連接字符串匹配名為BreakAwayContext的上下文。因?yàn)樵谂渲梦募邪l(fā)現(xiàn)了一個(gè)條目,就不再使用約定來定位數(shù)據(jù)庫。連接字符串項(xiàng),也已經(jīng)被命名為DataAccess.BreakAwayContext,這是上下文的全名。

Controlling Database Name with DbContext Constructor

使用DbContext的構(gòu)造器控制數(shù)據(jù)庫名稱

You’ve seen how to set the connection string that your context will use via the configuration file; now let’s look at some ways to control the database connection from code. So far you have just used the default constructor on DbContext, but there are also a number of other constructors available. Most of these are for more advanced scenarios, which will be covered later in this book, but there are two constructors that allow you to affect the database being connected to.

你已經(jīng)看到如何通過配置文件中的連接字符串設(shè)置上下文,現(xiàn)在讓我們來看看使用代碼來控制數(shù)據(jù)庫連接的方法。到目前為止,您只使用過DbContext的默認(rèn)構(gòu)造函數(shù),還有一些其他可用的構(gòu)造函數(shù)可供使用。其中大部分是更高級(jí)的方法,這將在這本書中進(jìn)行介紹,有兩個(gè)構(gòu)造函數(shù)允許你影響連接到的數(shù)據(jù)庫。

If you added a connection string to your configuration file, as shown in the previous section, be sure to remove it before starting this section. Remember that the configuration file overrides everything, including the features you will see in this section.

小貼士:如果您添加了一個(gè)連接字符串到您的配置文件,如在上一節(jié)所示,開始本節(jié)之前,一定要去掉它。記住,配置文件壓倒一切,包括在本節(jié)的功能。

DbContext includes a constructor that takes a single string parameter to control the database name. If you use this constructor, the value you supply will be used in place of the fully qualified context name. Add a constructor to BreakAwayContext that accepts a string value for the database name and passes it to the base constructor (Example 6-3). Notice that you are also adding a default constructor to ensure that all the existing code from previous chapters continues to work.

DbContext有一個(gè)構(gòu)造函數(shù)使用一個(gè)字符串參數(shù)來控制數(shù)據(jù)庫的名稱。如果您使用此構(gòu)造器,您提供的值將被用來代替context的全名。添加到BreakAwayContext構(gòu)造函數(shù)接受一個(gè)數(shù)據(jù)庫名稱的字符串值,并把它傳遞給基構(gòu)造器(例6-3)。請(qǐng)注意,您也必須要加入默認(rèn)的構(gòu)造器,以確保所有現(xiàn)有的代碼從前面的章節(jié)繼續(xù)工作。

Example 6-3. Database name constructor added to context

public BreakAwayContext() { } public BreakAwayContext(string databaseName): base(databaseName) { }

Modify the Main method to call a new SpecifyDatabaseName method (Example 6-4).

修改Main方法調(diào)用 SpecifyDatabaseName方法 (Example 6-4).

Example 6-4. SpecifyDatabaseName method added to application

static void Main() {SpecifyDatabaseName(); } private static void SpecifyDatabaseName() {using (var context =new BreakAwayContext("BreakAwayStringConstructor")){context.Destinations.Add(new Destination { Name = "Tasmania" });context.SaveChanges();} }

This new method uses the constructor you just added to specify a database name. This name is used instead of the fully qualified name of your context. Run the application and you will see that a database named BreakAwayStringConstructor has been created in your local SQL Express instance.

新方法使用的構(gòu)造器,就是你剛剛添加的,用于指定數(shù)據(jù)庫名稱。使用的此名稱,就不是上下文的全名了。運(yùn)行應(yīng)用程序,你會(huì)看到一個(gè)名為BreakAwayStringConstructor數(shù)據(jù)庫已在您的本地SQL Express實(shí)例中創(chuàng)建。

Controlling Connection String Name with DbContext Constructor
使用DbContext構(gòu)造器控制連接字符串

Earlier in this chapter, you saw that you are able to specify a database to use in the configuration file by adding a connection string with the same name as your context. If you use the DbContext constructor that accepts a database name, Entity ramework
will look for a connection string whose name matches the database name. In other words, with the default constructor, Entity Framework will look for a connection string named BreakAwayContext, but with the constructor used in Example 6-4, it will expect a connection string named BreakAwayStringConstructor.
You can also force the context to get its connection string from the configuration file by supplying name=[connection string name] to this constructor. This way, you don’t need to rely on name matching, since you are explicitly providing a connection string name. If no connection string is found with the specified name, an exception is thrown.

Example 6-5 shows how you can modify the default constructor of breakAwayContext to ensure that the connection string is always loaded from the configuration file.

在本章的前面,你看到,你可以通過在配置文件中加入與你的上下文的名稱相同的連接字符串指定一個(gè)數(shù)據(jù)庫。如果您使用的DbContext構(gòu)造函數(shù)接受一個(gè)數(shù)據(jù)庫名,EF框架就會(huì)尋找一個(gè)與連接字符串的名稱相匹配的數(shù)據(jù)庫的名稱。換句話說,默認(rèn)的構(gòu)造函數(shù),實(shí)體框架會(huì)尋找名為BreakAwayContext的連接字符串,而使用與示例6-4中使用的構(gòu)造函數(shù),它會(huì)期望一個(gè)名為BreakAwayStringConstructor的連接字符串。
您還可以強(qiáng)制上下文從配置文件中所提供的name= [connection string name]獲取連接字符串。這樣,你就不需要依靠名稱匹配,因?yàn)槟忝鞔_地提供了一個(gè)連接字符串。如果沒有找到有具體指定名稱的連接字符串,就會(huì)拋出一個(gè)異常。
例6-5顯示了如何修改breakAwayContext默認(rèn)構(gòu)造器,以確保連接字符串始終是從配置文件加載。

Example 6-5. Constructor defining which connection string should be loaded from? App.config

public BreakAwayContext():base("name=BreakAwayContext") { }
Reusing Database Connections
重用數(shù)據(jù)庫連接

DbContext has another constructor that allows you to supply a DbConnection instance.This can be useful if you have other application logic that works with a DbConnection or if you want to reuse the same connection across multiple contexts. To see this in action, add another constructor to BreakAwayContext that accepts a DbConnection and then passes the DbConnection to the base constructor, as shown in Example 6-6. You’ll also notice that you need to specify a value for the contextOwnsConnection. This argument controls whether or not the context should take ownership of the connection. If set to true, the connection will get disposed along with the context. If set to false,your code will need to take care of disposing the connection.

DbContext另一個(gè)構(gòu)造器,允許您提供一個(gè)DbConnection的實(shí)例。這可能是有用的,如果你有其他的應(yīng)用程序邏輯與DbConnection相關(guān),或者如果你想重用在多個(gè)環(huán)境下的同一個(gè)連接。要看到這種行為,添加另一個(gè)構(gòu)造器BreakAwayContext接受一個(gè)DbConnection,然后通過DbConnection基構(gòu)造器傳遞值,如例6-6所示。你還會(huì)發(fā)現(xiàn),你需要指定一個(gè)contextOwnsConnection的值。此參數(shù)控制context是否擁有連接的所有權(quán)。如果設(shè)置為true,連接將會(huì)隨上下文一起被釋放。如果設(shè)置為false,您的代碼將需要關(guān)注連接的釋放問題。

小貼士:添加這個(gè)構(gòu)造器你需要引用System.Data.Common名稱空間。

Example 6-6. DbConnection constructor added to context

public BreakAwayContext(DbConnection connection): base(connection, contextOwnsConnection: false) { }

Modify the Main method to call a new ReuseDbConnection method, as shown in
Example 6-7.

修改Main方法調(diào)用新的ReuseDbConnection方法,如Example 6-7所示:

小貼士:你需要引用System.Data.SqlClient名稱空間,因?yàn)榇舜a使用SqlConnection類型。

Example 6-7. ReuseDbConnection method added to application

static void Main() {ReuseDbConnection(); } private static void ReuseDbConnection() {var cstr = @"Server=.\SQLEXPRESS;Database=BreakAwayDbConnectionConstructor;Trusted_Connection=true";using (var connection = new SqlConnection(cstr)){using (var context = new BreakAwayContext(connection)){context.Destinations.Add(new Destination { Name = "Hawaii" });context.SaveChanges();}using (var context = new BreakAwayContext(connection)){foreach (var destination in context.Destinations){Console.WriteLine(destination.Name);}}} }

The ReuseDbConnection constructs a SqlConnection and then reuses it to construct two separate BreakAwayContext instances. In the example, the SqlConnection is just constructed from a connection string that is defined in code. However, Code First isn’t concerned with where you got the connection. You could be getting this connection string from a resource file. You may also be using some existing components that give you an existing DbConnection instance.

ReuseDbConnection構(gòu)造一個(gè)SqlConnection,然后重用它來構(gòu)造兩個(gè)單獨(dú)的BreakAwayContext實(shí)例。在這個(gè)例子中,在SqlConnection是在代碼中定義的連接字符串。然而,Code First并不關(guān)心你否獲得連接。您可以從資源文件該連接字符串。您也可以使用一些現(xiàn)有的組件,讓您獲得現(xiàn)有的DbConnection的實(shí)例。

Controlling Database Location with Connection Factories
使用連接工廠控制數(shù)據(jù)庫位置

One final option for controlling the database that is used is by swapping out the convention that Code First is using. The convention that Code First uses is available via Database.DefaultConnectionFactory. Connection factories implement the IDbConnectionFactory interface and are responsible for taking the name of a context and creating a DbConnection pointing to the database to be used. Entity Framework includes two connection factory implementations and you can also create your own.

控制所使用的數(shù)據(jù)庫的一個(gè)最后的選擇是通過更換Code First使用默認(rèn)約一。Code First使用約定是通過Database.DefaultConnectionFactory來進(jìn)行。連接工廠實(shí)現(xiàn)IDbConnectionFactory接口,并負(fù)責(zé)上下文的命名,并指明為要使用的數(shù)據(jù)庫創(chuàng)建一個(gè)DbConnection。EF框架包含兩個(gè)連接工廠實(shí)現(xiàn),你也可以創(chuàng)建自己的。

Working with SqlConnectionFactory
使用SqlConnectionFactory

The default connection factory for Code First is SqlConnectionFactory. This connection factory will use the SQL Client (System.Data.SqlClient) database provider to connect to a database. The default behavior will select a database on localhost\SQLEXPRESS using the fully qualified name of the context type as the database name. Integrated authentication will be used for authenticating with the database server.
You can override parts of this convention by specifying segments of the connection string that are to be set for any connection it creates. These segments are supplied to the constructor of SqlConnectionFactory using the same syntax used in connection strings. For example, if you wanted to use a different database server, you can specify the Server segment of the connection string:

Code First的默認(rèn)連接工廠是SqlConnectionFactory。此連接工廠將使用SQL Client(System.Data.SqlClient的)數(shù)據(jù)庫引擎連接到數(shù)據(jù)庫。默認(rèn)的行為,將選擇在localhost\ SQLEXPRESS創(chuàng)建數(shù)據(jù)庫,并使用上下文類型的完全限定名作為數(shù)據(jù)庫的名稱。集成身份驗(yàn)證,將用于與數(shù)據(jù)庫服務(wù)器進(jìn)行身份驗(yàn)證。
你可以通過指定的連接字符串段,來覆寫默認(rèn)規(guī)則。這些片段使用SqlConnectionFactory構(gòu)造函數(shù)相同的語法,在連接字符串中使用。例如,如果你想使用不同的數(shù)據(jù)庫服務(wù)器,您可以指定服務(wù)器段的連接字符串:

Database.DefaultConnectionFactory =new SqlConnectionFactory("Server=MyDatabaseServer");

Alternatively, you may want to use different credentials to connect to the database server:

可選地,你也可使用不同的驗(yàn)證方式來連接數(shù)據(jù)庫服務(wù)器:

Database.DefaultConnectionFactory =new SqlConnectionFactory("User=MyUserName;Password=MyPassWord;");

Working with SqlCeConnectionFactory

使用SqlCeConnectionFactory
Entity Framework also includes SqlCeConnectionFactory, which uses SQL Compact Client to connect to SQL Server Compact Edition databases. By default the database file name matches the fully qualified name of the context class and is created in the |ApplicationData| directory.

EF框架還包括SqlCeConnectionFactory,它使用SQL Compact Client 連接到SQL ServerCompact Edition數(shù)據(jù)庫。默認(rèn)情況下,數(shù)據(jù)庫文件名匹配上下文類的完全限定名,創(chuàng)建在| ApplicationData|目錄。(對(duì)可執(zhí)行程序而言,| ApplicationData|位于應(yīng)用程序所在目錄,對(duì)web應(yīng)用程序,伴于網(wǎng)站根目錄下的的App_Data子目錄內(nèi)。

Installing SQL Server Compact Edition
Before using SQL Server Compact Edition, you need to install the runtime. The runtime is available as an installer or via NuGet. Install the SqlServerCompact NuGet package to your BreakAwayConsole project. You can install the NuGet package by right-clicking on the References folder in your BreakAwayConsole project and selecting “Add Library Package Reference….” Select “Online” from the left menu and then search for “SqlServerCompact.”

小貼士:安裝SQL Server Compact Edition

在使用SQL Server Compact Edition前,需要進(jìn)行安裝。可以通過NuGet來進(jìn)行安裝。安裝SqlServerCompact 的NuGet包的到你的BreakAwayConsole項(xiàng)目的方法是:右鍵單擊項(xiàng)目并選擇:Add Library Package Reference….,從彈出的對(duì)話框中選擇Online并查找SqlServerCompact.

Modify the Main method, as shown in Example 6-8, to set the SqlCeConnectionFactory, and then call the InsertDestination method you created back in Chapter 2. The connection factories are included in the System.Data.Entity.Infrastructure namespace, so you will need to add a using for this. Be sure to read the rest of this section before running the code.

修改Main方法,如代碼6-8所示,設(shè)置SqlCeConnectionFactory,然后調(diào)用InsertDestination方法(第2章創(chuàng)建)。連接工廠包含在System.Data.Entity.Infrastructure名稱空間,需要添加對(duì)其的引用。在運(yùn)行代碼前請(qǐng)讀完本節(jié)。

Example 6-8. Changing the default connection factory

static void Main() {Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BreakAwayContext>());Database.DefaultConnectionFactory =new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");InsertDestination(); }

Notice that you need to specify a string that identifies the database provider to use (known as the provider invariant name). This string is chosen by the provider writer to uniquely identify the provider. Most providers keep the same identifier between versions, but SQL Compact uses a different identifier for each version. This is because SQL Compact providers are not backwards-compatible (you can’t use, for example,the 4.0 provider to connect to a 3.5 database). The SqlCeConnectionFactory needs to know what version of the provider to use, so it requires you to supply this string.
If you want to test out this code, you will need to make a small change to your model. Back in Chapter 3, we configured Trip.Identifier to be a database-generated key. Identifier is a GUID property and SQL Server had no problem generating values for us. SQL Compact, however, isn’t able to generate values for GUID columns. If you want to run the application, remove either the Data Annotation or Fluent API call that configures Trip.Identifier as database-generated.
Once you’ve made this change, you can run the application and you will notice that a DataAccess.BreakawayContext.sdf file is created in the output directory of your application (Figure 6-2). Now that you’ve seen SQL Compact in action, go ahead and reenable the configuration to make Trip.Identifier database-generated.

請(qǐng)注意,您需要指定一個(gè)字符串,標(biāo)識(shí)數(shù)據(jù)庫引擎(稱為provider invariant name)。這個(gè)字符串是數(shù)據(jù)庫供應(yīng)商提供的唯一標(biāo)識(shí)。大多數(shù)供應(yīng)商保持不同版本之間使用相同的標(biāo)識(shí)符,但SQL Compact為每個(gè)版本使用不同的標(biāo)識(shí)符。這是因?yàn)镾QL Compact數(shù)據(jù)庫引擎并不向后兼容的,例如,您不能使用4.0引擎連接到一個(gè)3.5數(shù)據(jù)庫。SqlCeConnectionFactory需要知道provider使用的版本,所以它需要你提供這個(gè)字符串。
如果你想測試一下這個(gè)代碼,你需要到你的模型一個(gè)小的變化。早在第3章,我們配置Trip.Identifier為數(shù)據(jù)庫生成的key。標(biāo)識(shí)符是一個(gè)GUID屬性,在SQL Server下沒有任何問題。 SQL Compact,不能產(chǎn)生的GUID列的值。如果你想運(yùn)行該應(yīng)用程序,刪除或注釋掉Data Annotations或Fluent API配置的Trip.Identifier(作為數(shù)據(jù)庫生成列)。
一旦你做出了這種變化,你可以運(yùn)行該應(yīng)用程序,你會(huì)發(fā)現(xiàn)一個(gè)DataAccess.BreakawayContext.sdf文件是在您的應(yīng)用程序的輸出目錄(圖6-2)創(chuàng)建。現(xiàn)在,你已經(jīng)看到SQL默認(rèn)規(guī)則的行為,繼續(xù)前進(jìn),重新啟用以前的配置,使Trip.Identifier能夠在數(shù)據(jù)庫里生成。

Writing a custom connection factory
寫一個(gè)定制的連接工廠

So far you have seen the connection factories that are included in Entity Framework, but you can also write your own by implementing the IDbConnectionFactory Interface.The interface is simple and contains a single CreateConnection method that accepts the context name and returns a DbConnection.
In this section, you’ll build a custom connection factory that is very similar to SqlConnectionFactory, except it will just use the context class name, rather than its fully qualified name for the database. You’ll also build this custom factory so that it will remove the word Context if it’s found in the context name.
Start by adding a CustomConnectionFactory class to your DataAccess project (Example 6-9).

到目前為止,您已經(jīng)看到,連接工廠已經(jīng)包含EF框架中,但你也可以通過實(shí)現(xiàn)IDbConnectionFactory接口來創(chuàng)建自已的連接工廠。
這個(gè)接口很簡單,包含了一個(gè)單一的創(chuàng)建連接的方法,它接受上下文的名稱,并返回一個(gè)DbConnection。
在本節(jié)中,您將構(gòu)建一個(gè)自定義的連接工廠,與SqlConnectionFactory非常相似,但它將只使用上下文類的名稱,而不是使用全名作為數(shù)據(jù)庫的名稱。您還可以定制這個(gè)工廠,當(dāng)其發(fā)現(xiàn)名稱中包含Context字符串時(shí)將刪除它。
加入一個(gè)CustomConnectionFactory類到DataAccess項(xiàng)目(代碼6-9)。

Example 6-9. Custom connection factory implementation

using System.Data.Common; using System.Data.Entity.Infrastructure; using System.Data.SqlClient; using System.Linq; namespace DataAccess {public class CustomConnectionFactory : IDbConnectionFactory{public DbConnection CreateConnection(string nameOrConnectionString){var name = nameOrConnectionString.Split('.').Last().Replace("Context", string.Empty);var builder = new SqlConnectionStringBuilder{DataSource = @".\SQLEXPRESS",InitialCatalog = name, IntegratedSecurity = true,MultipleActiveResultSets = true};return new SqlConnection(builder.ToString());}} }

The CustomConnectionFactory implementation uses the Split method to take the section of the context name after the final period to use for the database name. It then replaces any instances of the Context word with an empty string. Then it uses SqlConnection StringBuilder to create a connection string that is then used to construct a SqlConnection.
With this method in place, you can modify the Main method to make use of the custom connection factory you just created (Example 6-10). You do so by setting the Custom ConnectionFactory as the DefaultConnectionFactory before other code, which will be using a context.

CustomConnectionFactory使用Split方法取得上下文的名稱的最后一段(以“.”劃分)作為數(shù)據(jù)庫名稱。然后,它將Context字符串替換為空字符串字(如果有的話)。然后,它使用SqlConnection的StringBuilder創(chuàng)建一個(gè)連接字符串,將其用于構(gòu)造一個(gè)SqlConnection。
有了這個(gè)方法,你可以修改Main方法,使用剛剛創(chuàng)建的自定義連接工廠(例6-10)。這樣就DefaultConnectionFactory或其他代碼之前,讓上下文設(shè)置使用自定義的ConnectionFactory。

Example 6-10. Default connection factory set to new custom factory

static void Main() {Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BreakAwayContext>());Database.DefaultConnectionFactory = new CustomConnectionFactory();InsertDestination(); }

Run the application and you will see that a new “BreakAway” database is created on the local SQL Express instance (Figure 6-3). The custom factory you just created has removed the namespace from the database name and also stripped the word “Context” from the end.

運(yùn)行程序你會(huì)在SQL Express實(shí)例中發(fā)現(xiàn)一個(gè)新“BreakAway”數(shù)據(jù)庫創(chuàng)建了。定制工廠已經(jīng)替你將數(shù)據(jù)庫名的名稱空間和后綴Context刪除。

Working with Database Initialization
數(shù)據(jù)庫初始化

In Chapter 2, you saw that an initializer can be set for a context type using the Database.SetInitializer method. The initializer you set allowed the database to be dropped and recreated whenever the model changed:

在第2章,你已經(jīng)學(xué)習(xí)到可以使用Database.SetInitializer方法來為上下文類型設(shè)置初始化。設(shè)置初始化器可以清除并在模型變化時(shí)重建數(shù)據(jù)庫:

Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BreakAwayContext>());

Initialization involves two main steps. First, the model is created in memory using the Code First conventions and configuration discussed in previous chapters. Second, the database that will be used to store data is initialized using the database initializer that has been set. By default, this initialization will use the model that Code First calculated to create a database schema for you. Initialization will occur one time per application instance; in .NET Framework applications, the application instance is also referred to as an AppDomain. Initialization is triggered the first time that the context is used. Initialization occurs lazily, so creating an instance of the context is not enough to cause initialization to happen. An operation that requires the model must be performed, such as querying or adding entities.

The initialization process is thread-safe, so multiple threads in the same AppDomain can use the same context type. DbContext itself is not threadsafe, so a given instance of the context type must only be used in a single thread.

初始化包括兩個(gè)主要步驟。首先,使用Code First在內(nèi)存中根據(jù)默認(rèn)規(guī)則和配置創(chuàng)建模型。其次,使用已設(shè)置的數(shù)據(jù)庫初始化器將用于存儲(chǔ)數(shù)據(jù)的數(shù)據(jù)庫初始化。默認(rèn)情況下,這個(gè)初始化將使用Code First創(chuàng)建一個(gè)數(shù)據(jù)庫架構(gòu)的模型。初始化會(huì)發(fā)生在每一個(gè).NET Framework應(yīng)用程序的實(shí)例上。應(yīng)用程序的實(shí)例也被稱為一個(gè)AppDomain。當(dāng)上下文被使用時(shí),初始化第一次被引發(fā)。初始化是延遲加載的,所以創(chuàng)建一個(gè)實(shí)例的是不完全滿足初始化發(fā)生的條件的。必須執(zhí)行對(duì)模型的操作,如查詢或添加實(shí)體才會(huì)發(fā)生。
初始化過程是線程安全的,所以在同一AppDomain中的多個(gè)線程可以使用相同的上下文類型。 DbContext本身不是線程安全的,因此,必須只能在一個(gè)單獨(dú)的線程中使用一個(gè)給定的上下文類型實(shí)例。

Controlling When Database Initialization Occurs
在數(shù)據(jù)庫初始化產(chǎn)生時(shí)進(jìn)行控制

There are situations where you may want to control when initialization occurs, rather than leaving it to happen automatically the first time your context is used in an application instance. Initialization can be triggered using the DbContext.Database.Initialize method. This method takes a single boolean parameter named force. Supplying false will cause the initialization to occur only if it hasn’t yet been triggered in the current AppDomain. Remember that running the initializer once per AppDomain is the default behavior. Setting force to true will cause the initialization process to run even if it has already occurred in the current AppDomain. Because the context also triggers initialization, this code needs to run prior to the context being used in the AppDomain.
Why would you want to manually trigger database initialization? You may want to?
manually trigger initialization so that any errors that occur during model creation and database initialization can be caught and processed in a single place. Another reason? to force initialization to occur would be to front-load the cost of creating a large and/or complex model.
Let’s see this in action. Modify the Main method, adding in code to force database?? initialization to occur, and handle any exceptions that occur as a result of building the model (Example 6-11).

有的情況下,您可能希望控制初始化的發(fā)生,而不是讓它自動(dòng)發(fā)生在應(yīng)用程序?qū)嵗械谝淮问褂蒙舷挛膶?duì)象時(shí)。初始化可以使用DbContext.Database.Initialize方法觸發(fā)。這個(gè)方法接受一個(gè)名為force的布爾參數(shù)。該參數(shù)為false將導(dǎo)致初始化只發(fā)生在尚未在當(dāng)前AppDomain觸發(fā)的情況。請(qǐng)記住,每個(gè)AppDomain運(yùn)行初始化一次,就會(huì)執(zhí)行默認(rèn)行為一次。force設(shè)置為true時(shí)將會(huì)使初始化過程運(yùn)行,即使它已經(jīng)在當(dāng)前AppDomain發(fā)生。因?yàn)樯舷挛囊灿|發(fā)初始化,此代碼需要運(yùn)行在上下文被AppDomain使用之前。
為什么你想手動(dòng)觸發(fā)數(shù)據(jù)庫初始化?您可能需要通過手動(dòng)觸發(fā)初始化,使模型的創(chuàng)建和數(shù)據(jù)庫初始化過程中發(fā)生的任何錯(cuò)誤可以被捕獲,并在一個(gè)地方處理。強(qiáng)制初始化發(fā)生的另一個(gè)原因是為了前端加載大型和/或復(fù)雜的模型。
讓我們來看看這個(gè)行為。修改Main方法,在代碼中加入強(qiáng)制數(shù)據(jù)庫初始化的配置,處理模型構(gòu)建時(shí)發(fā)生的任何異常(代碼6-11)。

Example 6-11. Main method updated to process initialization errors

static void Main() {Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BreakAwayContext>());using (var context = new BreakAwayContext()){try{context.Database.Initialize(force: false);}catch (Exception ex){Console.WriteLine("Initialization Failed...");Console.WriteLine(ex.Message);}} }

Now we’ll make a change that will cause initialization to fail by asking Code First to map a numeric property to a string column. Doing this will cause the model creation process to fail before Code First even tries to create the database schema.
Modify Activity and add in a Column annotation that specifies a varchar data type to be used for the ActivityId property (Example 6-12).

現(xiàn)在我們做些更改以使用初始化失敗。這個(gè)錯(cuò)誤發(fā)生在Code First映射一個(gè)數(shù)值屬性到字符串列中。這樣做會(huì)使模型創(chuàng)建失敗發(fā)生在試圖創(chuàng)建數(shù)據(jù)庫構(gòu)架之前。

修改Activity類加入一個(gè)Data Annotations的Column特性標(biāo)記指定AcitivityId屬性使用varchar數(shù)據(jù)類型。(代碼6-12)

Example 6-12. ActivityId mapped to an incompatible database type

public class Activity {[Column(TypeName = "varchar")]public int ActivityId { get; set; }[Required, MaxLength(50)]public string Name { get; set; }public List<Trip> Trips { get; set; } }

Run the application and the program will display the exception informing us that the? data type that was specified is not valid because of the invalid cast:

運(yùn)行程序?qū)@示異常信息,表示不能將整形數(shù)據(jù)映射到varchar類型:

Initialization Failed...
Schema specified is not valid. Errors:

(122,12) : error 2019: Member Mapping specified is not valid. The type 'Edm.Int32[Nullable=False,DefaultValue=]' of member 'ActivityId' in type 'DataAccess.Activity' is not compatible with 'SqlServer.varchar[Nullable=False,DefaultValue=,MaxLength=8000,Unicode=False,FixedLength=False,StoreGeneratedPattern=Identity]' of member 'ActivityId' in type 'CodeFirstDatabaseSchema.Activity'.

(146,10) : error 2019: Member Mapping specified is not valid. The type 'Edm.Int32[Nul-lable=False,DefaultValue=]' of member 'ActivityId' in type 'DataAccess.Activity' is not compatible with 'SqlServer.varchar[Nullable=False,DefaultValue=,MaxLength=8000,Unicode=False,FixedLength=False]' of member 'Activity_ActivityId' in type 'CodeFirstDatabaseSchema.ActivityTrip'.

Remove the annotation you just added to DestinationId and run the application again.This time there will be no error.

移除剛剛添加到DestinationId上的特性標(biāo)記,再次運(yùn)行程序。這次就沒有問題了。

Switching Off Database Initialization Completely
關(guān)閉數(shù)據(jù)庫初始化功能

Of course, not every scenario calls for the database to be automatically initialized, and Entity Framework caters to these situations, too. For example, if you are mapping to an existing database, you probably want Code First to error if it can’t connect to the database, rather than trying to magically create one for you. You can switch off initialization by passing null to Database.SetInitializer:
Database.SetInitializer(null);
When the initializer is set to null, DbContext.Database.Initialize can still be used to? force model creation to occur.

當(dāng)然,并不是所有場景都需要自動(dòng)調(diào)用初始化,EF框架滿足所有情況。例如,如果你映射到一個(gè)現(xiàn)有的數(shù)據(jù)庫,可能在不能連接到數(shù)據(jù)庫時(shí)需要讓Code First發(fā)生錯(cuò)誤而不是魔法般地創(chuàng)建一下。你可以通過傳遞一個(gè)null參數(shù)到Database.SetInitializer來關(guān)閉初始化功能:

Database.SetInitializer(null); 當(dāng)初始化器被設(shè)置為null后,DbContext.Database.Initialize 仍可用于模型的創(chuàng)建過程.
Database Initializers Included in Entity Framework
將數(shù)據(jù)庫初始化器包含在EF框架

You’ll notice that Database.SetInitializer accepts an instance of IDatabaseInitializer<TContext>. There are three implementations of this interface included in Entity Framework. These implementations are abstract, so you can derive from them and customize the behavior. We’ll walk through creating your own implementation a little later on.
CreateDatabaseIfNotExists
This is the default initializer that is set for all contexts unless Database.SetInitializer is used to specify an alternative initializer. This is the safest initializer, as the database will never be dropped automatically, causing data loss. We saw in Chapter 2 that if the model is changed from when the database was created, an exception is thrown during initialization:

你會(huì)發(fā)現(xiàn),Database.SetInitializer接受IDatabaseInitializer<TContext>的一個(gè)實(shí)例。在EF框架中有三個(gè)針對(duì)此接口的實(shí)現(xiàn)。這些實(shí)現(xiàn)是抽象的,所以你可以從其中派生或自定義行為。后面我們將引導(dǎo)您逐步創(chuàng)建自己的實(shí)現(xiàn)。
CreateDatabaseIfNotExists
除非Database.SetInitializer指定了替代的初始化器,所有上下文都會(huì)被設(shè)置給默認(rèn)初始化器。這是最安全的初始化,數(shù)據(jù)庫將永遠(yuǎn)不會(huì)被自動(dòng)刪除,造成數(shù)據(jù)丟失。我們看到在第2章,如果模型是從數(shù)據(jù)庫時(shí)創(chuàng)建后發(fā)生的改變,在初始化期間會(huì)拋出異常:

The model backing the “BreakAwayContext” context has changed since the data-
base was created. Either manually delete/update the database, or call Database.SetI
nitializer with an IDatabaseInitializer instance. For example, the DropCreateDa
tabaseIfModelChanges strategy will automatically delete and recreate the database,
and optionally seed it with new data.

Because this is the default initializer, you shouldn’t need to set it, but if you find a need to you can use the following code:

由于默認(rèn)初始化器的存在,如果需要執(zhí)行下列代碼,你不需要做任何設(shè)置:

Database.SetInitializer(new CreateDatabaseIfNotExists<BreakAwayContext>());

DropCreateDatabaseWhenModelChanges
You’ve seen this initializer used throughout the previous chapters to make sure the? database always matches the current model. If Code First detects that the model and database do not match, the database will be dropped and recreated so that it matches the current model. This is useful during development, but you obviously wouldn’t want to use this when deploying your application, as it will result in data loss. We’ve already seen the code required to set this initializer:

從前面幾章你已經(jīng)看到要確保數(shù)據(jù)庫總是匹配當(dāng)前的模型.如果Code First檢測到二者不匹配,數(shù)據(jù)庫就人被刪除并且重新創(chuàng)建以便可以滿足匹配關(guān)系.在開發(fā)時(shí)這很有用,但是顯然不在在程序部署中使用,這樣數(shù)的會(huì)丟失.我們已經(jīng)看到這樣的設(shè)置初始化的代碼:

Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BreakAwayContext>());

DropCreateDatabaseAlways
This initializer will drop and recreate the database regardless of whether the model matches the database or not. At first glance, you may wonder why you would ever want to do that. If you are writing integration tests that exercise your whole application stack, it can be useful to have a way to reset the database to a well-known state before running a test. Modify the Main method as shown in Example 6-13 to
run some code that could represent a test that uses your application to insert a? single Destination.

這一初始化器將不管模型與數(shù)據(jù)庫匹配與否都會(huì)刪除和重建數(shù)據(jù)庫.你可能會(huì)疑惑為什么要這么做.如果你集成測試的整個(gè)應(yīng)用程序,就會(huì)需要在運(yùn)行測試前將數(shù)據(jù)庫重置到一個(gè)已知的狀態(tài).修改Main方法(代碼6-13),運(yùn)行一些代表測試的代碼,這會(huì)在應(yīng)用程序中插入一個(gè)Destinaion.
Example 6-13. Implementation of a pseudo integration test

static void Main() {Database.SetInitializer(new DropCreateDatabaseAlways<BreakAwayContext>());RunTest(); } private static void RunTest() {using (var context = new BreakAwayContext()){context.Destinations.Add(new Destination { Name = "Fiji" });context.SaveChanges();}using (var context = new BreakAwayContext()){if (context.Destinations.Count() == 1){Console.WriteLine("Test Passed: 1 destination saved to database");}else{Console.WriteLine("Test Failed: {0} destinations saved to database",context.Destinations.Count());}} }

Because the initializer is set to drop and recreate the database each time, you know that the database will be empty before the test starts. You won’t always want the database to be empty before running integration tests, and we’ll look at seeding data a little later on. Go ahead and run the application, and we will see that the test passes. So far we have just executed a single test, but normally there would be multiple tests required to test an application. Update the Main method so that it runs the same test twice in a row (Example 6-14).

由于初始化器被設(shè)置為每次都刪除并重建,你會(huì)知道在測試開始前數(shù)據(jù)庫是空的.你不用總是去考慮在運(yùn)行測試前數(shù)據(jù)庫是否為空,后而我們會(huì)看到放置一些種子數(shù)據(jù)在里面的例子.運(yùn)行程序,我們會(huì)看到測試通過.就目前為止我們只執(zhí)行一個(gè)單一的測試,通常一個(gè)應(yīng)用程序里面需要進(jìn)行多個(gè)測試.更新Main方法以便使其可以在一行里運(yùn)行兩次測試(代碼6-14):

Example 6-14. Main updated to run the test twice

static void Main(string[] args) {Database.SetInitializer(new DropCreateDatabaseAlways<BreakAwayContext>());RunTest();RunTest(); }

Run the application, and you will see that the first execution of the test method will succeed but the second one will fail, stating that there are two destinations in the database. The second test is failing because the data from the first execution is still in the database. This is happening because AppDomain only runs the initializer once by default.
Earlier in this chapter, you learned that you can use Database.Initialize to force initialization to occur, even if has already happened in the current AppDomain. Modify the RunTest method to include a call to Database.Initialize with force set to true to ensure the database is reset before each test (Example 6-15). Run the application again and you will see both tests now pass. The database is getting dropped and recreated in the well-known state before each execution.

運(yùn)行程序,你會(huì)看到第一個(gè)方法通過而第二個(gè)失敗,表明數(shù)據(jù)庫中有兩個(gè)destinations.第二個(gè)測試失敗的原因是第一次執(zhí)行的結(jié)果已經(jīng)在數(shù)據(jù)庫中了.進(jìn)一步的原因是AppDomaing默認(rèn)情況每次程序運(yùn)行只執(zhí)行一次初始化.

本章前面介紹可以使用Database.Initialize強(qiáng)制初始化,不管當(dāng)前的AppDomain是否已經(jīng)初始化過.修改RunTest方法包含一個(gè)調(diào)用Database.Initialize強(qiáng)制初始化的方法確保每次測試前都會(huì)重置數(shù)據(jù)庫(代碼6-15),再次運(yùn)行程序你會(huì)發(fā)現(xiàn)測方式現(xiàn)在通過了在每次測試執(zhí)行前.數(shù)據(jù)庫先刪除又以已知的狀態(tài)進(jìn)行重建.

Example 6-15. RunTest updated to force initialization

static void RunTest() {using (var context = new BreakAwayContext()){context.Database.Initialize(force: true);context.Destinations.Add(new Destination { Name = "Fiji" });context.SaveChanges();}using (var context = new BreakAwayContext()){if (context.Destinations.Count() == 1){Console.WriteLine("Test Passed: 1 destination saved to database");}else{Console.WriteLine("Test Failed: {0} destinations saved to database", context.Destinations.Count());}} }

Dropping and recreating the database is an easy way to start each test with a well-known state, but it can be expensive if you are running a lot of integration tests. Consider using System.Transactions.TransactionScope as a way to avoid changes being permanently saved to the database during each test.

刪除和重建數(shù)據(jù)庫是將數(shù)據(jù)庫狀態(tài)保持在一個(gè)已知狀態(tài)的很容易的方法,但是如果運(yùn)行一系集成的測試,系統(tǒng)開銷過大.考慮使用System.Transactions.TransactionScope作為避免在每一次測試時(shí)永久存儲(chǔ)對(duì)數(shù)據(jù)庫的修改.

Creating a Custom Database Initializer
創(chuàng)建一個(gè)定制的數(shù)據(jù)庫初始化器

So far, you have used the initializers that are included in the Entity Framework API. There may be times when the initialization logic that you want doesn’t align with any of the included initializers. Fortunately Database.SetInitializer accepts the IDatabaseInitializer interface, which you can implement to provide your own logic.

到目前為止,我們一直在使用EF框架中包含的初始化器.有時(shí)不想按照已有的初始化器的邏輯進(jìn)行工作.Database.SetInitializer 接受IDatabaseInitializer 接口,你可以通過實(shí)現(xiàn)這個(gè)接口來定制邏輯.

As well as writing your own custom initializers, you can also find initializers that other people have created. One example of this is available in the EFCodeFirst.CreateTablesOnly NuGet package. This initializer will allow you to drop and create the tables in an existing database, rather than dropping and creating the actual database itself. This is particularly useful if you are targeting a hosted database where you don’t have permission to drop or create the entire database.

小貼士:除了自已寫定制的初始化器,也可以引用別人創(chuàng)建的.有一個(gè)例子EFCodeFirst.CreateTablesOnly NuGet 包.這個(gè)初始化器允許你在已經(jīng)存在的數(shù)據(jù)庫進(jìn)行刪除和創(chuàng)建操作,而不是刪除和創(chuàng)建數(shù)據(jù)庫實(shí)體本身.當(dāng)你將數(shù)據(jù)庫指向一個(gè)宿主數(shù)據(jù)庫而又沒有權(quán)限刪除和創(chuàng)建整個(gè)數(shù)據(jù)庫時(shí)特別有用.

There could be any number of reasons you want to implement your own initializer. We are going to look at a simple scenario where the developer will be prompted before the database is dropped and recreated. The Database property exposes a variety of methods to interact with the database such as checking to see if it exists, creating it, or dropping? it. The three initializers that are included in the API contain logic that leverages these methods. You can combine the methods in logic in your own class. That’s what you'll do in this next example. Add the PromptForDropCreateDatabaseWhenModelChages class to your DataAccess project (Example 6-16).

你想實(shí)現(xiàn)自己的初始化器的原因可能有很多。我們來看一個(gè)簡單的場景:在數(shù)據(jù)庫刪除并重新創(chuàng)建之前給開發(fā)者一個(gè)提示。Database屬性暴露了各種方法與數(shù)據(jù)庫進(jìn)行交互,可以實(shí)現(xiàn)檢查是否存在,是否創(chuàng)建,或是否刪除等功能。API中包含的初始化器包含的邏輯利用了這些方法。在你自己的類,你也可以將這些方法整合在邏輯里。這就是下面這個(gè)例子要做的。添加PromptForDropCreateDatabaseWhenModelChages類到您的DataAccess項(xiàng)目(例6-16)。
Example 6-16. Custom initializer

using System; using System.Data.Entity; namespace DataAccess {public class PromptForDropCreateDatabaseWhenModelChages<TContext>: IDatabaseInitializer<TContext>where TContext : DbContext{public void InitializeDatabase(TContext context){// If the database exists and matches the model// there is nothing to dovar exists = context.Database.Exists();if (exists && context.Database.CompatibleWithModel(true)){return;}// If the database exists and doesn't match the model// then prompt for inputif (exists){Console.WriteLine("Existing database doesn't match the model!");Console.Write("Do you want to drop and create the database? (Y/N): ");var res = Console.ReadKey();Console.WriteLine();if (!String.Equals("Y",res.KeyChar.ToString(),StringComparison.OrdinalIgnoreCase)){return;}context.Database.Delete();}// Database either didn't exist or it didn't match// the model and the user chose to delete itcontext.Database.Create();}} }

The PromptForDropCreateDatabaseWhenModelChages class implements a single InitializeDatabase method. First, it checks if the database exists and matches the current model. If it does, there is nothing else to be done and the initializer returns. If the database exists but doesn’t match the current model, you will be prompted to see if you want to drop and create the database. If you decide not to recreate the database, the initializer returns and Entity Framework will attempt to run against the existing database schema. If you do decide to recreate the database, the existing database is dropped. The final line of code simply creates the database and is only reached if the database didn’t exist or if we chose to recreate the database.
The custom initializer now needs to be registered with the Entity Framework; modify the Main method to take care of this (Example 6-17). You’ll notice that we’re also updating Main so that it calls the InsertDestination method that we wrote back in Chapter 2.

PromptForDropCreateDatabaseWhenModelChages類實(shí)現(xiàn)單一的InitializeDatabase方法。首先,它檢查數(shù)據(jù)庫是否存在以及是否與當(dāng)前的模型相匹配。如果是這樣,什么也不做,初始化器返回。如果該數(shù)據(jù)庫存在,但不匹配當(dāng)前的模型,會(huì)提示你是否想刪除和創(chuàng)建數(shù)據(jù)庫。如果您決定不重新創(chuàng)建數(shù)據(jù)庫,初始化器返順,EF框架將嘗試按現(xiàn)有的數(shù)據(jù)庫模式再次運(yùn)行。如果您決定重新創(chuàng)建數(shù)據(jù)庫,現(xiàn)有的數(shù)據(jù)庫將被刪除。最后一行代碼簡單地創(chuàng)建數(shù)據(jù)庫中,只會(huì)在數(shù)據(jù)庫不存在,或者我們選擇重新創(chuàng)建數(shù)據(jù)庫才會(huì)得到執(zhí)行。
自定義的初始器在需要在EF框架內(nèi)注冊(cè);修改Main方法(例6-17)。你會(huì)注意到Main方法調(diào)用了我們?cè)诘?章更新的InsertDestination方法:

Example 6-17. Custom initializer registered in Main

static void Main() {Database.SetInitializer(newPromptForDropCreateDatabaseWhenModelChages<BreakAwayContext>());InsertDestination(); }

Let’s go ahead and change the model so that it no longer matches the database. Modify the Destination class by adding a MaxLength annotation to the Name property:

我們對(duì)模型作些修改使其不再與數(shù)據(jù)庫匹配.修改Destinaton類中的Name屬性,在其上附加一個(gè)Data Annotations標(biāo)記:MaxLength.

[MaxLength(200)] public string Name { get; set; }

Now run the application, and you will be prompted, asking if you want to drop and Create the database. Answer no (N) to tell our custom initializer to leave the database alone this time. You’ll notice that the application still completes successfully. This is because the changes you made don’t prevent Entity Framework from being able to use the current model to access the out-of-date database schema. Entity Framework expects that Destination names should be 200 characters or less. Since the database didn’t change, it doesn’t enforce max length, so it’s happy with the insert statement that Entity Framework is sending to the database.
Now let’s make a change that will affect the insert statement. Modify the Destination class to include a new TravelWarnings property:

現(xiàn)在運(yùn)行的應(yīng)用程序,將提示您,詢問您是否要?jiǎng)h除并創(chuàng)建數(shù)據(jù)庫。答否(N),告訴我們的自定義初始化器不理會(huì)數(shù)據(jù)庫。你會(huì)注意到,應(yīng)用程序仍然成功完成。這是因?yàn)槟龅母牟粫?huì)阻止EF框架使用當(dāng)前模型訪問過時(shí)的數(shù)據(jù)庫架構(gòu)。EF框架預(yù)期Destination Names應(yīng)為200個(gè)字符或更少。由于數(shù)據(jù)庫沒有改變,它沒有強(qiáng)制執(zhí)行的最大長度,所以EF框架給它發(fā)送的INSERT語句可以執(zhí)行。
現(xiàn)在,讓我們做出改變,會(huì)影響INSERT語句。修改目標(biāo)類,包括一個(gè)新的TravelWarnings屬性:

public string TravelWarnings { get; set; }

Run the application again. As before, you’ll be prompted, asking if you want to drop and create the database. Select not to recreate the database again, and this time you will get a DbUpdateException. You’ll need to drill through the inner exceptions to find the actual cause of the error (Figure 6-4).
The inner exception of the top-level exception is an UpdateException, and the inner exception of that is a SqlException. The SqlException finally has the message that explains what happened: “Invalid column name 'TravelWarnings'.” The problem is that Entity Framework is trying to execute the SQL shown in Example 6-18, but the TravelWarnings column doesn’t exist in the database.

再次運(yùn)行應(yīng)用程序。像以前一樣,你會(huì)被提示,詢問您是否要?jiǎng)h除并創(chuàng)建數(shù)據(jù)庫。選擇不創(chuàng)建數(shù)據(jù)庫,這個(gè)時(shí)候你會(huì)得到一個(gè)DbUpdateException。你需要通過內(nèi)部異常鏈去找到錯(cuò)誤的真正原因(圖6-4)。
頂層異常的內(nèi)部異常是UpdateException,該內(nèi)部異常是一個(gè)SQLException。最后的SQLException的消息,說明發(fā)生了什么:“無效的列名稱”TravelWarnings,“問題發(fā)生的原因是EF框架試圖執(zhí)行示例6-18中所示的SQL語句,但TravelWarnings列在數(shù)據(jù)庫中不存在。

Example 6-18. Invalid SQL being executed

insert [dbo].[Destinations]([Name], [Country], [Description],[TravelWarnings], [Photo]) values (@0, @1, @2, null, null) select [DestinationId] from [dbo].[Destinations] where @@ROWCOUNT > 0 and [DestinationId] = scope_identity()

Run the application again, but this time select to drop and recreate the database when prompted. The application will now execute successfully.

再次運(yùn)行程序,這次選擇刪除并重建數(shù)據(jù)庫,程序成功執(zhí)行.

Setting Database Initializers from a Configuration File
在配置文件中設(shè)置數(shù)據(jù)庫初始化器

Setting initializers in code is an easy way to get started while developing, but when it’s time to deploy your application, you probably want to have an easier way to set them without modifying code. It’s highly unlikely you want to deploy your application with the DropCreateDatabaseIfModelChanges initializer set in production! Add an appSettings section to the config file of your BreakAwayConsole project that includes the initializer setting shown in Example 6-19.

在代碼中設(shè)置的初始化是一種簡單的方法,但部署用程序時(shí),您可能希望有一個(gè)更簡單的方式設(shè)置,而無需修改代碼。想要應(yīng)用程序部署設(shè)置DropCreateDatabaseIfModelChanges的初始化器,這是極不可能的!將appSettings節(jié)添加到BreakAwayConsole項(xiàng)目的配置文件中,其中包括了初始化器的設(shè)置,見示例6-19中所示。
Example 6-19. Initializer set in configuration file

<?xml version="1.0"?> <configuration><appSettings><add key="DatabaseInitializerForType DataAccess.BreakAwayContext, DataAccess"value="System.Data.Entity.DropCreateDatabaseIfModelChanges`1[[DataAccess.BreakAwayContext, DataAccess]], EntityFramework" /> </appSettings> </configuration>

小貼士:代碼示例有一行斷裂的代碼,在實(shí)際的App.config文件中應(yīng)該刪除.value值必須在同一行才能工作.

There is a lot going on in the line of configuration, so let’s break down how it is structured. The key section always starts off with DatabaseInitializerForType followed by a space, then the assembly qualified name of the context that the initializer is being set for. In our case that is DataAccess.BreakAwayContext, DataAccess, which simply means the DataAccess.BreakAwayContext type that is defined in the DataAccess assembly. The value section is the assembly qualified name of the database initializer to be used. It looks complex because we are using a generic type; we are setting DropCreateDatabaseIfModelChanges<BreakAwayContext> defined in the EntityFramework assembly.
Also modify the Main method so that it no longer sets an initializer in code:

還應(yīng)有很多配置行,我們打破配置結(jié)構(gòu)來分別研究。關(guān)鍵部分開始于DatabaseInitializerForType,后跟一個(gè)空格,然后配置正確的上下文名稱以便初始化器能夠?yàn)槠湓O(shè)置。在我們的例子就是DataAccess.BreakAwayContext,DataAccess,僅僅意味著DataAccess.BreakAwayContext類型的定義是在DataAccess程序集。Value部分是配置數(shù)據(jù)庫初始化器要使用名稱。它看起來復(fù)雜,因?yàn)槲覀兪褂梅盒皖愋?#xff0c;我們使用了EF框架程序集中定義的DropCreateDatabaseIfModelChanges<BreakAwayContext> 方法來進(jìn)行設(shè)置。
還需要修改Main方法,以便它不再設(shè)置在代碼中的初始化:

static void Main() {InsertDestination(); }

Now make a change to the model so that you can test that the entry in our configuration file is being used. Modify the Destination class to include a new ClimateInfo property:

現(xiàn)在對(duì)模型作些改變以便測試配置文件是否得到應(yīng)用.修改Destination類包含一個(gè)新的ClimateInfor屬性:

public string ClimateInfo { get; set; }

Run the application, and you will see that the database gets dropped and recreated with the new ClimateInfo column.

運(yùn)行程序,你會(huì)看到數(shù)據(jù)庫被刪除重建,新增ClimateInfo列,
Now if you want to deploy your application, you may want to change the initializer to CreateDatabaseIfNotExists so that you never incur automatic data loss. You may also be working with a DBA who is going to create the database for you. If the database is being created outside of the Code First workflow, you will want to switch off? database initialization altogether. You can do that by changing the configuration file to specify Disabled for the initializer (Example 6-20).
現(xiàn)在,如果你要部署你的應(yīng)用程序,你可能變更初始化器為CreateDatabaseIfNotExists,以便永遠(yuǎn)不會(huì)導(dǎo)致數(shù)據(jù)丟失。您也可能工作在別人為您創(chuàng)建的DBA上,如果數(shù)據(jù)庫在Code First工作流之外創(chuàng)建,你會(huì)想禁用數(shù)據(jù)庫的初始化。你可以通過改變配置文件來指定初始化器的禁用(代碼6-20).

Example 6-20. Initializer disabled in configuration file

<?xml version="1.0"?> <configuration><appSettings><add key="DatabaseInitializerForType DataAccess.BreakAwayContext, DataAccess"value="Disabled" /></appSettings> </configuration>

Now that we’ve explored setting database initializers in a config file, be sure to remove any settings that you have added.

現(xiàn)在我探索了有關(guān)在配置文件設(shè)置初始化器的方法,請(qǐng)移除已經(jīng)添加的任何設(shè)置.

Using Database Initializers to Seed Data

數(shù)據(jù)庫數(shù)據(jù)庫初始化器添加種子數(shù)據(jù)
In this chapter, you have seen how database initializers can be used to control how and when Code First creates the database. So far, the database that Code First creates has always been empty, but there are situations where you may want Code First to create your database with some seed data. You may have some lookup tables that have a predefined set of data, such as Gender or Country. You may just want some sample data in your database while you are working locally so that you can see how your application behaves.
Another scenario where seed data can be useful is running integration tests. In the previous section, we wrote a test that relied on an empty database; now let’s write one that relies on a database containing some well-known data.
Let’s start by writing the test you are going to run. Modify the Main method to run a test that verifies there is a Destination entry for “Great Barrier Reef” in our database (Example 6-21). Be sure you have removed any settings you added to the config file in the previous section.

在本章中,你已經(jīng)看到數(shù)據(jù)庫的初始化可以被用來控制Code First何時(shí)以及如何創(chuàng)建數(shù)據(jù)庫。到目前為止,Code First創(chuàng)建的數(shù)據(jù)庫一直是空的,但也有一些需要Code First創(chuàng)建一些種子數(shù)據(jù)的情況。您可能有一些預(yù)定義的數(shù)據(jù),如性別或國家的查找表。或者你可能只是想在本地工作時(shí),在數(shù)據(jù)庫中放一些示例數(shù)據(jù),從而可以看到應(yīng)用程序的行為。
種子數(shù)據(jù)可以用另一種情況是運(yùn)行集成測試。在上一節(jié)中,我們寫了一個(gè)測試,依靠的是一個(gè)空的數(shù)據(jù)庫,現(xiàn)在讓我們進(jìn)行一個(gè)依賴于包含一些已知數(shù)據(jù)的數(shù)據(jù)庫的測試。
讓我們開始寫要運(yùn)行的測試。修改Main方法來運(yùn)行測試,以驗(yàn)證“Great Barrier Reef”是否為數(shù)據(jù)庫中的Destination條目(例6-21).確保您已經(jīng)刪除在上一節(jié)添加到任何設(shè)置的配置文件。

Example 6-21. Implementation of pseudo test reliant on seed data

static void Main() {Database.SetInitializer(new DropCreateDatabaseAlways<BreakAwayContext>());GreatBarrierReefTest(); } static void GreatBarrierReefTest() {using (var context = new BreakAwayContext()){var reef = from destination in context.Destinationswhere destination.Name == "Great Barrier Reef"select destination;if (reef.Count() == 1){Console.WriteLine("Test Passed: 1 'Great Barrier Reef' destination found");}else{Console.WriteLine("Test Failed: {0} 'Great Barrier Reef' destinations found",context.Destinations.Count());}} }

Run the application, and you will see that the test fails, stating that there are no entries for “Great Barrier Reef” in the database. This makes sense, because you set the DropCreateDatabaseAlways initializer, which will create and empty the database for us.
What the test really needs is a variation of DropCreateDatabaseAlways that will insert? some seed data after it has created the database. The three initializers that are included in the Entity Framework are not sealed, meaning you can create your own initializer that derives from one of the included ones. All three of the included initializers also include a Seed method that is virtual (Overridable in Visual Basic), meaning it can be overridden. The seed method has an empty implementation, but the initializers will call it at the appropriate time to insert seed data that you provide.
To check out this feature, add a DropCreateBreakAwayWithSeedData class to your DataAccess project. The key to providing the seed data is to override the initializer’s Seed method, as shown in Example 6-22.

運(yùn)行應(yīng)用程序,你會(huì)看到測試失敗,說明“Great Barrier Reef”在數(shù)據(jù)庫中沒有任何條目與之匹配。這是有道理的,因?yàn)槟阍O(shè)置了DropCreateDatabaseAlways初始化,這將創(chuàng)建和清空數(shù)據(jù)庫。
測試真正需要的是,在創(chuàng)建了數(shù)據(jù)庫后,將插入一些種子數(shù)據(jù),能夠DropCreateDatabaseAlways的變化來實(shí)現(xiàn)。包括在EF框架中的三個(gè)初始化器不是sealed的,這意味著你可以通過派生其中之一來創(chuàng)建自己的初始化器。所有三個(gè)初始化器都包括一個(gè)名為Seed的abstract方法(在Visual Basic中為Overridable),這意味著它可以被覆寫。Seed方法有一個(gè)空的實(shí)現(xiàn),但是,初始化器可以在適當(dāng)?shù)臅r(shí)候插入您提供的種子數(shù)據(jù)。
要檢查此功能,您的DataAccess項(xiàng)目添加DropCreateBreakAwayWithSeedData類。提供種子數(shù)據(jù)的關(guān)鍵是覆寫初始化種子的方法,如例6-22所示。

Example 6-22. Initializer with seed data implemented

using System.Data.Entity; using Model; namespace DataAccess {public class DropCreateBreakAwayWithSeedData :DropCreateDatabaseAlways<BreakAwayContext>{protected override void Seed(BreakAwayContext context){context.Destinations.Add(new Destination{ Name = "Great Barrier Reef" });context.Destinations.Add(new Destination{ Name = "Grand Canyon" });}} }

Notice that there is no call to context.SaveChanges() at the end of the Seed method in Example 6-24. The base Seed method will call that for you after the code in your custom method has been executed. If you let Visual Studio’s editor auto-implement the override method for you, it will include a call to base.Seed(context). You can leave that in if you like, but be sure to let it be the last line of code in the method.

小貼士:注意我們?cè)谶@里沒有調(diào)用SaveChanges方法.Seed的基方法會(huì)在定制方法之后調(diào)用.如果你讓VS的編輯器自動(dòng)實(shí)現(xiàn)覆寫方法,就會(huì)包括一個(gè)對(duì)base.Seed(context)的調(diào)用.你可以不去管他,但是記住要將這行代碼放在方法的最后一行.

Now that you have created an initializer that will insert seed data, it needs to be registered with Entity Framework so that it will be used. This is achieved in same way that we registered the included initializers earlier—via the Database.SetInitializer
method.

現(xiàn)在你已經(jīng)創(chuàng)建了一個(gè)能夠插入種子數(shù)據(jù)的初始化器,它需要在EF框架中注冊(cè)后才能被使用.這可以以我們?cè)谇懊姘跏蓟飨嗤姆绞竭M(jìn)行--通過Database.SetInitializer方法

Modify the Main method so that DropCreateBreakAwayWithSeedData is registered (Example 6-23).

修改Main方法以注冊(cè)DropCreateBreakAwayWithSeedData類:
Example 6-23. Initializer with seed data is registered

static void Main() {Database.SetInitializer(new DropCreateBreakAwayWithSeedData());GreatBarrierReefTest(); }

Run the application again, and the test will pass this time because Code First is now using DropCreateBreakAwayWithSeedData to initialize the database. Because this initializer derives from DropCreateDatabaseAlways, it will drop the database and recreate and empty one. The Seed method that you overrode will then be called and the seed data you specified is inserted into the newly created database each time.

再次運(yùn)行應(yīng)用程序,本次測試通過,因?yàn)镃ode First現(xiàn)在使用DropCreateBreakAwayWithSeedData初始化數(shù)據(jù)庫。由于此初始化派生自DropCreateDatabaseAlways,它會(huì)刪除數(shù)據(jù)庫并重新創(chuàng)建一個(gè)空數(shù)據(jù)庫。覆寫的Seed方法,隨后被調(diào)用,您指定的種子數(shù)據(jù)插入到了新創(chuàng)建的數(shù)據(jù)庫里。

The Seed method in Example 6-24 is a great first look at seeding the database but somewhat simplistic. You can insert various types of data and related data as well. For an example of an efficient LINQ method used to insert entire graphs of related data in Seed, check out my blog post, Seeding a Database with Code First.

代碼6-24中的Seed方法或許有些簡單化,但這讓我們很好地觀察了這個(gè)方法的創(chuàng)建過程。可以插入各類數(shù)據(jù)及相關(guān)數(shù)據(jù)。例如使用一個(gè)有效率的LINQ方法利用Code First檢查我的博客,將相關(guān)文章的全部圖片作為種子插入數(shù)據(jù)庫。

Using Database Initialization to Further Affect Database Schema
使用數(shù)據(jù)庫初始化進(jìn)一步影響數(shù)據(jù)庫構(gòu)架

In addition to seeding a database when Code First creates it, you may want to affect the database in ways that can’t be done with configurations or data seeding. For example, you may want to create an Index on the Name field of the Lodgings table to speed up searches by name.
You can achieve this by calling the DbContext.Database.ExecuteSqlCommand method along with the SQL to create the index inside the Seed method. Example 6-24 shows the modified Seed method that forces this Index to be created before the data is inserted.

除了使用Code First在數(shù)據(jù)庫中創(chuàng)建種子數(shù)據(jù)以外,你也可不使用配置或種子數(shù)據(jù)達(dá)到相同目的.你如,你可以想創(chuàng)建Lodgings表中Name字段的索引以加快使用name查詢的速度.

你可以通過調(diào)用DbContext.Database.ExecuteSqlCommand 方法來達(dá)到目的,這個(gè)方法會(huì)在Seed方法內(nèi)部構(gòu)造創(chuàng)建索引的SQL語句.代碼6-24顯示了對(duì)Seed方法的修改,強(qiáng)制數(shù)據(jù)插入時(shí)創(chuàng)建索引.

Example 6-24. Using the ExecuteSqlCommand to add an Index to the database

protected override void Seed(BreakAwayContext context) {context.Database.ExecuteSqlCommand("CREATE INDEX IX_Lodgings_Name ON Lodgings (Name)");context.Destinations.Add(new Destination{ Name = "Great Barrier Reef" });context.Destinations.Add(new Destination{ Name = "Grand Canyon" }); }
Summary
小結(jié)

In this chapter you saw how Code First interacts with the database by default, and how you can override this default behavior. You’ve learned how to control the database that Code First connects to and how that database is initialized. You’ve also seen how database initializers can be used in scenario tests to insert seed data into the database as it is initialized.
Throughout this book, you have seen how Code First creates a model based on your
domain classes and configuration. You’ve then seen how Code First locates and initializes the database that the model will be used to access. In the next chapter, you will learn about some advanced concepts that you probably won’t use regularly, but you may find useful from time to time.

在這一章中,你看到了默認(rèn)情況Code First如何與數(shù)據(jù)庫進(jìn)行交互,也學(xué)習(xí)到如何覆寫此默認(rèn)行為。你已經(jīng)學(xué)會(huì)了如何控制數(shù)據(jù)庫,Code First連接到數(shù)據(jù)庫時(shí)是如何初始化的。您還學(xué)到如何將數(shù)據(jù)庫的初始化用于情景測試中,如何在初始化時(shí)插入種子數(shù)據(jù)。
在這本書中,你已經(jīng)看到Code First根據(jù)您的域類和配置創(chuàng)建了一個(gè)模型,然后,你也看到Code First是如何定義和初始化被模型用來訪問的數(shù)據(jù)庫。在下一章中,您將學(xué)習(xí)一些不太常用的先進(jìn)的理念,但這些理念有時(shí)會(huì)很有用。

轉(zhuǎn)載于:https://www.cnblogs.com/guolihao/p/3208943.html

總結(jié)

以上是生活随笔為你收集整理的Code First :使用Entity. Framework编程(6) ----转发 收藏的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

一本大道久久东京热无码av | 国产va免费精品观看 | 国产内射爽爽大片视频社区在线 | 国产女主播喷水视频在线观看 | 精品人人妻人人澡人人爽人人 | 日韩av无码一区二区三区不卡 | 久久精品国产精品国产精品污 | 国产精品怡红院永久免费 | 亚洲阿v天堂在线 | 欧美亚洲日韩国产人成在线播放 | 国产亚洲精品久久久久久国模美 | 中文字幕无线码免费人妻 | 亚洲中文字幕va福利 | 亚洲男人av香蕉爽爽爽爽 | 亚洲男女内射在线播放 | 欧美丰满熟妇xxxx | 亚洲中文字幕va福利 | 欧洲精品码一区二区三区免费看 | 亚洲色成人中文字幕网站 | 97无码免费人妻超级碰碰夜夜 | 精品国产麻豆免费人成网站 | 久久国产36精品色熟妇 | 亚洲国产一区二区三区在线观看 | 午夜时刻免费入口 | 网友自拍区视频精品 | 最近免费中文字幕中文高清百度 | 国产成人无码午夜视频在线观看 | 国产 精品 自在自线 | 在线精品亚洲一区二区 | a在线观看免费网站大全 | 色婷婷香蕉在线一区二区 | 无码国产乱人伦偷精品视频 | 久久综合给久久狠狠97色 | 荫蒂被男人添的好舒服爽免费视频 | 欧美丰满少妇xxxx性 | 日日摸夜夜摸狠狠摸婷婷 | 国产综合久久久久鬼色 | 亚洲小说图区综合在线 | 国语精品一区二区三区 | 婷婷五月综合缴情在线视频 | 国产九九九九九九九a片 | 少妇高潮一区二区三区99 | 久久精品国产大片免费观看 | 亚洲精品一区二区三区在线观看 | 九九久久精品国产免费看小说 | 激情五月综合色婷婷一区二区 | 日本精品人妻无码免费大全 | 无码一区二区三区在线 | 色婷婷欧美在线播放内射 | 欧美国产日韩久久mv | 亚洲中文字幕成人无码 | 欧洲熟妇色 欧美 | 国产又粗又硬又大爽黄老大爷视 | 精品国偷自产在线 | 亚洲高清偷拍一区二区三区 | 中文精品无码中文字幕无码专区 | 成在人线av无码免费 | 色五月丁香五月综合五月 | 欧美日韩久久久精品a片 | 国产精品国产三级国产专播 | 大胆欧美熟妇xx | 真人与拘做受免费视频 | 亚洲欧洲中文日韩av乱码 | 漂亮人妻洗澡被公强 日日躁 | 人妻aⅴ无码一区二区三区 | 日韩精品a片一区二区三区妖精 | 国产热a欧美热a在线视频 | 精品无码国产一区二区三区av | www一区二区www免费 | 亚洲精品无码国产 | 国产精品久久福利网站 | 狠狠色噜噜狠狠狠7777奇米 | 麻花豆传媒剧国产免费mv在线 | 久久久久人妻一区精品色欧美 | 一本色道婷婷久久欧美 | 精品无码av一区二区三区 | 波多野结衣一区二区三区av免费 | 欧美性生交活xxxxxdddd | 亚洲精品国产第一综合99久久 | 人妻中文无码久热丝袜 | 国产成人无码av在线影院 | 亚洲第一网站男人都懂 | 亚洲经典千人经典日产 | 在线播放无码字幕亚洲 | 日本va欧美va欧美va精品 | 色婷婷欧美在线播放内射 | 性啪啪chinese东北女人 | 人人澡人人妻人人爽人人蜜桃 | 粗大的内捧猛烈进出视频 | 日本精品久久久久中文字幕 | 对白脏话肉麻粗话av | 最近免费中文字幕中文高清百度 | 少女韩国电视剧在线观看完整 | 国产人妻久久精品二区三区老狼 | 日日噜噜噜噜夜夜爽亚洲精品 | 精品久久久中文字幕人妻 | 国产亚洲人成a在线v网站 | 欧洲vodafone精品性 | 亚洲欧洲无卡二区视頻 | 欧美日韩人成综合在线播放 | 永久免费精品精品永久-夜色 | 国产午夜福利100集发布 | 乱码av麻豆丝袜熟女系列 | 久久久av男人的天堂 | 女人被爽到呻吟gif动态图视看 | 中文字幕无码日韩专区 | 丰满肥臀大屁股熟妇激情视频 | 久久久久人妻一区精品色欧美 | 丰满人妻翻云覆雨呻吟视频 | 亚洲精品成人福利网站 | 亚欧洲精品在线视频免费观看 | 99在线 | 亚洲 | 亚洲成av人综合在线观看 | 青春草在线视频免费观看 | 荫蒂被男人添的好舒服爽免费视频 | 亚洲精品国产a久久久久久 | 久久综合狠狠综合久久综合88 | 欧美丰满老熟妇xxxxx性 | 一区二区三区高清视频一 | 亚洲国产av精品一区二区蜜芽 | 久久亚洲中文字幕精品一区 | 丰满人妻被黑人猛烈进入 | 中文精品无码中文字幕无码专区 | 亚洲中文字幕乱码av波多ji | 天堂а√在线中文在线 | 色综合久久久久综合一本到桃花网 | 国产成人一区二区三区在线观看 | 国产精品久久国产精品99 | 黑人玩弄人妻中文在线 | 中文字幕无码av激情不卡 | 成年美女黄网站色大免费全看 | 亚洲毛片av日韩av无码 | 在线播放无码字幕亚洲 | 久久精品成人欧美大片 | 三级4级全黄60分钟 | 又粗又大又硬毛片免费看 | 亚洲欧美精品aaaaaa片 | 2020久久香蕉国产线看观看 | 大屁股大乳丰满人妻 | 国产精品多人p群无码 | 波多野42部无码喷潮在线 | 综合人妻久久一区二区精品 | 娇妻被黑人粗大高潮白浆 | 奇米影视888欧美在线观看 | √8天堂资源地址中文在线 | 国产精品亚洲综合色区韩国 | 麻豆人妻少妇精品无码专区 | 日日摸夜夜摸狠狠摸婷婷 | 国产色在线 | 国产 | 国产尤物精品视频 | www国产精品内射老师 | 国产精品办公室沙发 | 久久国产精品二国产精品 | 4hu四虎永久在线观看 | 日韩精品a片一区二区三区妖精 | 纯爱无遮挡h肉动漫在线播放 | 小鲜肉自慰网站xnxx | 人人妻人人澡人人爽欧美一区 | 偷窥村妇洗澡毛毛多 | 欧洲精品码一区二区三区免费看 | 久久综合色之久久综合 | 久久精品人人做人人综合试看 | 亚洲区小说区激情区图片区 | 国产免费观看黄av片 | 久久精品人妻少妇一区二区三区 | 亚洲精品一区二区三区大桥未久 | 亚洲中文字幕无码中字 | 76少妇精品导航 | 精品人妻人人做人人爽夜夜爽 | 国产97人人超碰caoprom | 久久综合九色综合97网 | 无码午夜成人1000部免费视频 | 99国产欧美久久久精品 | 88国产精品欧美一区二区三区 | 男人的天堂2018无码 | 精品无码av一区二区三区 | 日韩 欧美 动漫 国产 制服 | 亚洲精品一区二区三区在线观看 | 亚欧洲精品在线视频免费观看 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产国语老龄妇女a片 | 国产精品a成v人在线播放 | 色欲久久久天天天综合网精品 | 日韩少妇白浆无码系列 | 成人精品一区二区三区中文字幕 | 国产精品久久精品三级 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 欧美日韩一区二区综合 | 99精品国产综合久久久久五月天 | 一个人看的视频www在线 | 国产精品亚洲а∨无码播放麻豆 | 无码人妻精品一区二区三区不卡 | 久久综合给合久久狠狠狠97色 | 一本色道久久综合亚洲精品不卡 | 久久久精品国产sm最大网站 | 国产三级久久久精品麻豆三级 | 亚洲毛片av日韩av无码 | 精品成人av一区二区三区 | 夜先锋av资源网站 | 色一情一乱一伦一区二区三欧美 | 成人影院yy111111在线观看 | 精品厕所偷拍各类美女tp嘘嘘 | 熟女俱乐部五十路六十路av | 中文字幕中文有码在线 | 天天摸天天透天天添 | 亚洲精品一区二区三区婷婷月 | 欧美人与物videos另类 | 老熟妇乱子伦牲交视频 | 欧美日韩在线亚洲综合国产人 | 国产一区二区不卡老阿姨 | 成人无码视频免费播放 | 色五月丁香五月综合五月 | 亚洲一区二区三区 | 在线成人www免费观看视频 | 国产乱码精品一品二品 | 久久精品中文闷骚内射 | 波多野结衣一区二区三区av免费 | 久久视频在线观看精品 | 精品欧美一区二区三区久久久 | 99riav国产精品视频 | 精品 日韩 国产 欧美 视频 | 亚洲国产欧美日韩精品一区二区三区 | 国产乱人偷精品人妻a片 | 九九久久精品国产免费看小说 | 久久久久av无码免费网 | 国产亚洲精品精品国产亚洲综合 | 亚洲伊人久久精品影院 | 玩弄人妻少妇500系列视频 | 一本久道久久综合狠狠爱 | 我要看www免费看插插视频 | 亚洲精品一区二区三区大桥未久 | 欧美日韩亚洲国产精品 | 亲嘴扒胸摸屁股激烈网站 | 中文字幕日产无线码一区 | 国产精品永久免费视频 | 欧美人与动性行为视频 | 国产小呦泬泬99精品 | 精品久久久无码人妻字幂 | 精品人妻人人做人人爽夜夜爽 | 久久视频在线观看精品 | 无码帝国www无码专区色综合 | 中文字幕+乱码+中文字幕一区 | 日韩欧美中文字幕公布 | 国产亚洲欧美在线专区 | 国产乡下妇女做爰 | 免费中文字幕日韩欧美 | 免费视频欧美无人区码 | 大色综合色综合网站 | 欧美人妻一区二区三区 | 国产午夜手机精彩视频 | 俺去俺来也www色官网 | 成熟妇人a片免费看网站 | 久久国产精品萌白酱免费 | 亚洲色无码一区二区三区 | 亚洲高清偷拍一区二区三区 | 久久久中文字幕日本无吗 | 亚洲人成网站在线播放942 | 少妇被粗大的猛进出69影院 | 国产精品久久久久影院嫩草 | 最新国产麻豆aⅴ精品无码 | 男女猛烈xx00免费视频试看 | 蜜桃臀无码内射一区二区三区 | 3d动漫精品啪啪一区二区中 | 日本精品人妻无码免费大全 | 日本熟妇人妻xxxxx人hd | 亚洲国产精品无码久久久久高潮 | 香港三级日本三级妇三级 | 久久亚洲精品中文字幕无男同 | 精品亚洲韩国一区二区三区 | 熟妇激情内射com | 99er热精品视频 | 成人无码精品1区2区3区免费看 | 熟妇人妻无乱码中文字幕 | 国产超碰人人爽人人做人人添 | 午夜无码人妻av大片色欲 | 少妇高潮喷潮久久久影院 | av人摸人人人澡人人超碰下载 | 久久99热只有频精品8 | 久久99久久99精品中文字幕 | 亚洲国产av精品一区二区蜜芽 | 国产成人无码午夜视频在线观看 | 久久久久亚洲精品男人的天堂 | 麻豆国产人妻欲求不满谁演的 | 国产精品久久久久影院嫩草 | 中文字幕人妻丝袜二区 | 久久精品视频在线看15 | 内射巨臀欧美在线视频 | 久久久亚洲欧洲日产国码αv | 国产精品无码久久av | 久久精品国产日本波多野结衣 | 久久综合九色综合97网 | 好屌草这里只有精品 | 在线 国产 欧美 亚洲 天堂 | 国产亚洲精品久久久久久大师 | 麻豆果冻传媒2021精品传媒一区下载 | 国产午夜福利亚洲第一 | 国产精品二区一区二区aⅴ污介绍 | 香港三级日本三级妇三级 | 麻豆人妻少妇精品无码专区 | 理论片87福利理论电影 | 岛国片人妻三上悠亚 | 亚洲熟妇色xxxxx亚洲 | 一本久道高清无码视频 | 免费视频欧美无人区码 | 无码人妻黑人中文字幕 | 日本www一道久久久免费榴莲 | 好爽又高潮了毛片免费下载 | 国产麻豆精品一区二区三区v视界 | 亚洲国产精品一区二区第一页 | 亚洲精品一区二区三区在线 | 人人妻人人澡人人爽欧美精品 | 双乳奶水饱满少妇呻吟 | 午夜精品一区二区三区在线观看 | 两性色午夜免费视频 | 国产高潮视频在线观看 | 强奷人妻日本中文字幕 | 亚洲日韩av片在线观看 | 一本无码人妻在中文字幕免费 | 国产av无码专区亚洲a∨毛片 | 人人澡人摸人人添 | 少女韩国电视剧在线观看完整 | 东京一本一道一二三区 | 国产午夜精品一区二区三区嫩草 | 中国大陆精品视频xxxx | 东京热一精品无码av | 三上悠亚人妻中文字幕在线 | 色妞www精品免费视频 | 亚洲欧美日韩综合久久久 | 婷婷六月久久综合丁香 | 色欲人妻aaaaaaa无码 | 麻豆精产国品 | 欧美国产亚洲日韩在线二区 | 国产亚洲美女精品久久久2020 | 亚洲精品一区二区三区四区五区 | 成人一区二区免费视频 | 色综合久久久无码网中文 | 国产精品.xx视频.xxtv | 3d动漫精品啪啪一区二区中 | 免费乱码人妻系列无码专区 | 国产精品人人妻人人爽 | 国产熟女一区二区三区四区五区 | 国产97在线 | 亚洲 | 日韩av无码一区二区三区不卡 | 日韩av无码中文无码电影 | 亚洲国产成人av在线观看 | 免费无码一区二区三区蜜桃大 | 久久综合狠狠综合久久综合88 | 麻豆国产人妻欲求不满 | 人妻无码αv中文字幕久久琪琪布 | 国产在线精品一区二区高清不卡 | 老头边吃奶边弄进去呻吟 | 国产真实伦对白全集 | 欧美猛少妇色xxxxx | 精品aⅴ一区二区三区 | 欧美日韩一区二区综合 | 国产精品二区一区二区aⅴ污介绍 | 三级4级全黄60分钟 | 美女极度色诱视频国产 | 亚洲国产欧美日韩精品一区二区三区 | 在线成人www免费观看视频 | 美女毛片一区二区三区四区 | 毛片内射-百度 | 亚洲国产精品一区二区美利坚 | 又色又爽又黄的美女裸体网站 | 久久精品人人做人人综合试看 | 国产欧美熟妇另类久久久 | 蜜桃无码一区二区三区 | 国产精品高潮呻吟av久久 | 国产精品怡红院永久免费 | 水蜜桃色314在线观看 | 久久久精品欧美一区二区免费 | 日韩人妻少妇一区二区三区 | 蜜臀av无码人妻精品 | 欧美激情一区二区三区成人 | 岛国片人妻三上悠亚 | 无码人妻久久一区二区三区不卡 | 久久综合久久自在自线精品自 | 国产av无码专区亚洲awww | 国产内射爽爽大片视频社区在线 | 国产在线一区二区三区四区五区 | 人妻尝试又大又粗久久 | 又色又爽又黄的美女裸体网站 | 亚洲精品中文字幕久久久久 | 东京无码熟妇人妻av在线网址 | 免费无码肉片在线观看 | 熟女俱乐部五十路六十路av | 又大又硬又爽免费视频 | 婷婷色婷婷开心五月四房播播 | 2020久久超碰国产精品最新 | 久久国产劲爆∧v内射 | 欧美 丝袜 自拍 制服 另类 | 荫蒂被男人添的好舒服爽免费视频 | 国产 浪潮av性色四虎 | 精品无码国产自产拍在线观看蜜 | 伊人久久大香线蕉av一区二区 | 丰满人妻翻云覆雨呻吟视频 | 人妻体内射精一区二区三四 | 荫蒂添的好舒服视频囗交 | 色欲综合久久中文字幕网 | 天天躁日日躁狠狠躁免费麻豆 | 亚洲色在线无码国产精品不卡 | 亚洲精品午夜国产va久久成人 | 一本久久a久久精品亚洲 | 丰满人妻被黑人猛烈进入 | 日本精品高清一区二区 | 在线播放免费人成毛片乱码 | 成人免费视频视频在线观看 免费 | 亚洲欧美中文字幕5发布 | 欧美肥老太牲交大战 | 少妇无码吹潮 | 精品无码av一区二区三区 | 国产人妻人伦精品 | 丰满少妇熟乱xxxxx视频 | 九月婷婷人人澡人人添人人爽 | 97久久超碰中文字幕 | 久久人人爽人人爽人人片av高清 | 黑森林福利视频导航 | 在线播放无码字幕亚洲 | 精品少妇爆乳无码av无码专区 | 少妇邻居内射在线 | 国产凸凹视频一区二区 | 国产内射爽爽大片视频社区在线 | 亚洲欧美日韩国产精品一区二区 | 亚洲综合无码一区二区三区 | 无码纯肉视频在线观看 | aⅴ亚洲 日韩 色 图网站 播放 | 欧美野外疯狂做受xxxx高潮 | 亚洲区欧美区综合区自拍区 | 四十如虎的丰满熟妇啪啪 | 国产av一区二区精品久久凹凸 | 国产精品久久福利网站 | 高潮毛片无遮挡高清免费视频 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 国产人妻大战黑人第1集 | 伊人色综合久久天天小片 | 精品日本一区二区三区在线观看 | 成人试看120秒体验区 | 欧美国产亚洲日韩在线二区 | 亚洲国产精品成人久久蜜臀 | 国产在线一区二区三区四区五区 | 日本大香伊一区二区三区 | 亚洲国产成人a精品不卡在线 | 亚洲综合另类小说色区 | 午夜精品一区二区三区的区别 | 成 人 网 站国产免费观看 | 久9re热视频这里只有精品 | 四虎国产精品免费久久 | 国产热a欧美热a在线视频 | 精品熟女少妇av免费观看 | 色婷婷av一区二区三区之红樱桃 | 六十路熟妇乱子伦 | 无码人妻丰满熟妇区五十路百度 | 99国产精品白浆在线观看免费 | 国产精品毛多多水多 | 国产又粗又硬又大爽黄老大爷视 | 欧美国产日产一区二区 | 久久久久久国产精品无码下载 | 少妇无码一区二区二三区 | 初尝人妻少妇中文字幕 | 特黄特色大片免费播放器图片 | 少妇高潮喷潮久久久影院 | 午夜福利电影 | 无码人妻少妇伦在线电影 | 99麻豆久久久国产精品免费 | av人摸人人人澡人人超碰下载 | 成在人线av无码免观看麻豆 | 精品人妻中文字幕有码在线 | 网友自拍区视频精品 | 无套内射视频囯产 | 亚洲 a v无 码免 费 成 人 a v | 东京一本一道一二三区 | 色综合久久久久综合一本到桃花网 | 一本色道婷婷久久欧美 | 澳门永久av免费网站 | 性做久久久久久久免费看 | 丰满少妇熟乱xxxxx视频 | 欧美亚洲日韩国产人成在线播放 | 露脸叫床粗话东北少妇 | 国产亚洲欧美在线专区 | 夜夜高潮次次欢爽av女 | 一本久久伊人热热精品中文字幕 | 少妇人妻大乳在线视频 | 国产av无码专区亚洲awww | 狠狠cao日日穞夜夜穞av | 亚洲最大成人网站 | 亚洲午夜无码久久 | 无码人妻黑人中文字幕 | 午夜男女很黄的视频 | 97无码免费人妻超级碰碰夜夜 | 爱做久久久久久 | 中文精品无码中文字幕无码专区 | 亚洲国产欧美日韩精品一区二区三区 | 俄罗斯老熟妇色xxxx | 宝宝好涨水快流出来免费视频 | 欧美阿v高清资源不卡在线播放 | 国产精品免费大片 | √8天堂资源地址中文在线 | 色噜噜亚洲男人的天堂 | 精品久久8x国产免费观看 | 久久99精品国产.久久久久 | 日本xxxx色视频在线观看免费 | 人人妻人人澡人人爽人人精品 | 欧美高清在线精品一区 | 色噜噜亚洲男人的天堂 | 日日天干夜夜狠狠爱 | 国产特级毛片aaaaaa高潮流水 | 女人和拘做爰正片视频 | 日本一卡二卡不卡视频查询 | 丰满少妇女裸体bbw | 天堂一区人妻无码 | 精品国偷自产在线视频 | 少妇久久久久久人妻无码 | 97se亚洲精品一区 | 乌克兰少妇xxxx做受 | 久久久久亚洲精品中文字幕 | 亚洲毛片av日韩av无码 | 无遮挡国产高潮视频免费观看 | 青春草在线视频免费观看 | 少妇久久久久久人妻无码 | a在线观看免费网站大全 | 成人精品天堂一区二区三区 | 国产人妻精品一区二区三区 | 宝宝好涨水快流出来免费视频 | 小泽玛莉亚一区二区视频在线 | 内射爽无广熟女亚洲 | 国产精品99爱免费视频 | 国产三级久久久精品麻豆三级 | 国产情侣作爱视频免费观看 | 狠狠噜狠狠狠狠丁香五月 | 美女毛片一区二区三区四区 | 5858s亚洲色大成网站www | 中文毛片无遮挡高清免费 | 国产午夜无码视频在线观看 | 欧美日韩视频无码一区二区三 | 97se亚洲精品一区 | 亚洲无人区午夜福利码高清完整版 | 国产69精品久久久久app下载 | 亚洲成a人一区二区三区 | 偷窥村妇洗澡毛毛多 | аⅴ资源天堂资源库在线 | 樱花草在线播放免费中文 | 1000部夫妻午夜免费 | 国产精品久久福利网站 | 玩弄少妇高潮ⅹxxxyw | 狠狠色欧美亚洲狠狠色www | 成人免费视频视频在线观看 免费 | 亚洲aⅴ无码成人网站国产app | 亚洲欧美国产精品专区久久 | 十八禁真人啪啪免费网站 | 一区二区传媒有限公司 | 国内老熟妇对白xxxxhd | 中文久久乱码一区二区 | а√天堂www在线天堂小说 | 亚洲国产精品成人久久蜜臀 | 奇米影视888欧美在线观看 | 精品一区二区不卡无码av | 天堂久久天堂av色综合 | 午夜理论片yy44880影院 | 欧美人与禽zoz0性伦交 | 欧美日韩亚洲国产精品 | 无遮无挡爽爽免费视频 | 成人无码视频免费播放 | 国产亚洲人成在线播放 | аⅴ资源天堂资源库在线 | 最近中文2019字幕第二页 | 婷婷综合久久中文字幕蜜桃三电影 | 狠狠cao日日穞夜夜穞av | 日本高清一区免费中文视频 | 久久久久国色av免费观看性色 | 国产真实伦对白全集 | 樱花草在线社区www | 国产av无码专区亚洲awww | 久久国产精品精品国产色婷婷 | 伊在人天堂亚洲香蕉精品区 | 2020最新国产自产精品 | 亚洲欧洲日本综合aⅴ在线 | 日本又色又爽又黄的a片18禁 | 久久综合狠狠综合久久综合88 | 亚洲精品国偷拍自产在线麻豆 | 亚洲人成网站免费播放 | 久激情内射婷内射蜜桃人妖 | 野狼第一精品社区 | 亚洲另类伦春色综合小说 | 日本熟妇大屁股人妻 | 欧美成人高清在线播放 | 国产真人无遮挡作爱免费视频 | 内射白嫩少妇超碰 | 欧美激情综合亚洲一二区 | 日本乱偷人妻中文字幕 | 国产明星裸体无码xxxx视频 | 久久久精品欧美一区二区免费 | 国产午夜精品一区二区三区嫩草 | 中文字幕久久久久人妻 | 精品一区二区三区波多野结衣 | 天天拍夜夜添久久精品大 | 久久久久免费看成人影片 | aⅴ在线视频男人的天堂 | 欧美黑人巨大xxxxx | 帮老师解开蕾丝奶罩吸乳网站 | 男人和女人高潮免费网站 | 女人高潮内射99精品 | 亚洲综合伊人久久大杳蕉 | 少女韩国电视剧在线观看完整 | 漂亮人妻洗澡被公强 日日躁 | 在线 国产 欧美 亚洲 天堂 | 国产成人综合色在线观看网站 | 久久久精品456亚洲影院 | 一本久久伊人热热精品中文字幕 | 在线 国产 欧美 亚洲 天堂 | 帮老师解开蕾丝奶罩吸乳网站 | 一本一道久久综合久久 | 国内精品久久久久久中文字幕 | 国产综合色产在线精品 | 国产香蕉97碰碰久久人人 | 高潮毛片无遮挡高清免费视频 | 国产精品18久久久久久麻辣 | 亲嘴扒胸摸屁股激烈网站 | 久青草影院在线观看国产 | 精品国产青草久久久久福利 | 九月婷婷人人澡人人添人人爽 | 国产极品美女高潮无套在线观看 | 国内丰满熟女出轨videos | 国产麻豆精品一区二区三区v视界 | 人妻无码久久精品人妻 | 妺妺窝人体色www在线小说 | 成人无码精品一区二区三区 | 久久伊人色av天堂九九小黄鸭 | 亚洲国产高清在线观看视频 | 国产精品99爱免费视频 | 久久99精品国产麻豆 | 免费中文字幕日韩欧美 | 亚洲国产欧美日韩精品一区二区三区 | 亚洲精品一区二区三区在线 | 激情五月综合色婷婷一区二区 | 宝宝好涨水快流出来免费视频 | 国内精品人妻无码久久久影院蜜桃 | 免费人成网站视频在线观看 | 丰满少妇人妻久久久久久 | 亚洲一区二区三区播放 | 亚洲 激情 小说 另类 欧美 | 国产美女精品一区二区三区 | 亚洲乱码中文字幕在线 | 亚洲性无码av中文字幕 | 永久免费观看国产裸体美女 | 131美女爱做视频 | 白嫩日本少妇做爰 | 久久人人97超碰a片精品 | 小sao货水好多真紧h无码视频 | 日本精品人妻无码77777 天堂一区人妻无码 | 亚洲小说春色综合另类 | 国产在线精品一区二区高清不卡 | 丰满肥臀大屁股熟妇激情视频 | 国产成人无码a区在线观看视频app | 亚洲乱码国产乱码精品精 | 久精品国产欧美亚洲色aⅴ大片 | 久久久久久av无码免费看大片 | 国产人妻人伦精品1国产丝袜 | av无码久久久久不卡免费网站 | 色一情一乱一伦一视频免费看 | 荡女精品导航 | 色一情一乱一伦一视频免费看 | 在教室伦流澡到高潮hnp视频 | 精品aⅴ一区二区三区 | 日本一卡2卡3卡四卡精品网站 | 乱码午夜-极国产极内射 | 精品无码国产一区二区三区av | 四虎影视成人永久免费观看视频 | 婷婷六月久久综合丁香 | 国内揄拍国内精品少妇国语 | 日日橹狠狠爱欧美视频 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 亚洲中文字幕在线观看 | 少妇性l交大片欧洲热妇乱xxx | 国产无套粉嫩白浆在线 | 国产综合色产在线精品 | 福利一区二区三区视频在线观看 | 18禁黄网站男男禁片免费观看 | 好爽又高潮了毛片免费下载 | 国产亚洲精品久久久ai换 | 日产国产精品亚洲系列 | 午夜福利电影 | 欧洲美熟女乱又伦 | av无码久久久久不卡免费网站 | 无码吃奶揉捏奶头高潮视频 | 日日噜噜噜噜夜夜爽亚洲精品 | 99在线 | 亚洲 | 激情五月综合色婷婷一区二区 | 亚洲成熟女人毛毛耸耸多 | 国产亚洲精品精品国产亚洲综合 | 夜夜夜高潮夜夜爽夜夜爰爰 | 精品欧美一区二区三区久久久 | 中文字幕 人妻熟女 | 欧洲熟妇精品视频 | 大胆欧美熟妇xx | 精品无码av一区二区三区 | 亚洲日本va午夜在线电影 | 国产区女主播在线观看 | 国产在线精品一区二区高清不卡 | 午夜理论片yy44880影院 | 天下第一社区视频www日本 | 欧美 日韩 亚洲 在线 | 国内丰满熟女出轨videos | 亚洲精品一区二区三区四区五区 | 国产超碰人人爽人人做人人添 | 国语自产偷拍精品视频偷 | 亚洲一区二区三区含羞草 | 亚洲乱码国产乱码精品精 | 中文字幕无线码免费人妻 | 精品成人av一区二区三区 | 日韩少妇内射免费播放 | 乱码av麻豆丝袜熟女系列 | 国产精品igao视频网 | 男人的天堂av网站 | 77777熟女视频在线观看 а天堂中文在线官网 | 2019午夜福利不卡片在线 | 在线а√天堂中文官网 | 日本精品少妇一区二区三区 | 人妻互换免费中文字幕 | 人妻互换免费中文字幕 | www国产亚洲精品久久网站 | 少妇久久久久久人妻无码 | 亚洲无人区午夜福利码高清完整版 | 亲嘴扒胸摸屁股激烈网站 | 无码福利日韩神码福利片 | www国产亚洲精品久久久日本 | 一本久道久久综合狠狠爱 | 日日摸天天摸爽爽狠狠97 | 国产口爆吞精在线视频 | 牲欲强的熟妇农村老妇女 | 国内丰满熟女出轨videos | 麻豆蜜桃av蜜臀av色欲av | 一本大道伊人av久久综合 | 免费人成在线视频无码 | 色综合久久久无码中文字幕 | 99国产精品白浆在线观看免费 | 人妻aⅴ无码一区二区三区 | 牲欲强的熟妇农村老妇女 | av小次郎收藏 | 国产精品高潮呻吟av久久4虎 | 好爽又高潮了毛片免费下载 | 人人妻人人澡人人爽欧美一区九九 | aa片在线观看视频在线播放 | 熟妇女人妻丰满少妇中文字幕 | 麻豆国产丝袜白领秘书在线观看 | 无码人妻出轨黑人中文字幕 | 奇米影视7777久久精品人人爽 | 超碰97人人做人人爱少妇 | 国产激情无码一区二区 | 中文字幕无码免费久久9一区9 | 久久综合九色综合欧美狠狠 | 欧美人与禽猛交狂配 | 999久久久国产精品消防器材 | 国产一精品一av一免费 | 图片区 小说区 区 亚洲五月 | 色老头在线一区二区三区 | 欧洲vodafone精品性 | 大地资源中文第3页 | 免费视频欧美无人区码 | 奇米影视7777久久精品 | 色欲人妻aaaaaaa无码 | 一二三四社区在线中文视频 | 中文字幕av伊人av无码av | 中文字幕+乱码+中文字幕一区 | 欧美日韩在线亚洲综合国产人 | 国产精品久久福利网站 | 乱码av麻豆丝袜熟女系列 | 久久久国产一区二区三区 | 亚洲va中文字幕无码久久不卡 | 蜜桃av抽搐高潮一区二区 | 国产免费久久精品国产传媒 | 黑人巨大精品欧美黑寡妇 | 性欧美牲交在线视频 | 99久久精品无码一区二区毛片 | 99久久久无码国产精品免费 | 亚洲va中文字幕无码久久不卡 | 九九综合va免费看 | 蜜桃臀无码内射一区二区三区 | 无码一区二区三区在线观看 | 少妇被黑人到高潮喷出白浆 | 强辱丰满人妻hd中文字幕 | 亚洲区欧美区综合区自拍区 | 精品国精品国产自在久国产87 | 欧美喷潮久久久xxxxx | 亚洲国产欧美在线成人 | 少妇愉情理伦片bd | 小sao货水好多真紧h无码视频 | 亚洲精品欧美二区三区中文字幕 | 99久久精品无码一区二区毛片 | 亚洲男女内射在线播放 | 亚洲a无码综合a国产av中文 | 欧美性猛交xxxx富婆 | 又大又硬又黄的免费视频 | 国产在线精品一区二区三区直播 | 性欧美熟妇videofreesex | 国产免费久久久久久无码 | 帮老师解开蕾丝奶罩吸乳网站 | aⅴ亚洲 日韩 色 图网站 播放 | 亚洲国产日韩a在线播放 | 亚无码乱人伦一区二区 | 人妻插b视频一区二区三区 | 国产乱人无码伦av在线a | 日本va欧美va欧美va精品 | 欧美丰满熟妇xxxx性ppx人交 | 宝宝好涨水快流出来免费视频 | 波多野结衣高清一区二区三区 | 亚洲娇小与黑人巨大交 | 全球成人中文在线 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 久久综合激激的五月天 | √天堂中文官网8在线 | 国产精品美女久久久 | 无码国产乱人伦偷精品视频 | 白嫩日本少妇做爰 | 熟妇激情内射com | www国产亚洲精品久久网站 | 亚洲国产综合无码一区 | 99国产精品白浆在线观看免费 | 人妻少妇精品无码专区动漫 | 妺妺窝人体色www婷婷 | 国产成人精品三级麻豆 | 日欧一片内射va在线影院 | 日韩视频 中文字幕 视频一区 | 精品国产aⅴ无码一区二区 | 久久久久国色av免费观看性色 | 亚洲性无码av中文字幕 | 999久久久国产精品消防器材 | 精品人妻av区 | 国产精品久久久久9999小说 | 欧美大屁股xxxxhd黑色 | 久久无码人妻影院 | 中文无码成人免费视频在线观看 | 亚洲精品鲁一鲁一区二区三区 | 成人免费视频视频在线观看 免费 | 色婷婷综合激情综在线播放 | 久久久久久久久蜜桃 | 国产成人精品久久亚洲高清不卡 | 无码av免费一区二区三区试看 | 夜夜躁日日躁狠狠久久av | 少妇性荡欲午夜性开放视频剧场 | 图片区 小说区 区 亚洲五月 | 色窝窝无码一区二区三区色欲 | 国产精品美女久久久网av | 欧美 日韩 亚洲 在线 | 久久久久人妻一区精品色欧美 | 国产内射老熟女aaaa | 久久久久成人片免费观看蜜芽 | 精品一区二区三区波多野结衣 | 免费乱码人妻系列无码专区 | 国产av人人夜夜澡人人爽麻豆 | 中文无码成人免费视频在线观看 | 亚洲a无码综合a国产av中文 | 丝袜足控一区二区三区 | 久久综合色之久久综合 | 伊人久久大香线蕉av一区二区 | 亚洲无人区午夜福利码高清完整版 | 99久久人妻精品免费二区 | 大胆欧美熟妇xx | 亚洲欧美日韩综合久久久 | 国产精品久久久久影院嫩草 | 精品一区二区三区波多野结衣 | 久久精品国产99精品亚洲 | 久久99精品久久久久久动态图 | 亚洲日本在线电影 | 亚洲一区二区三区偷拍女厕 | 激情内射亚州一区二区三区爱妻 | 久久天天躁狠狠躁夜夜免费观看 | 日本精品人妻无码免费大全 | 成人亚洲精品久久久久软件 | 沈阳熟女露脸对白视频 | 麻豆精产国品 | 亚洲成av人影院在线观看 | 日本熟妇乱子伦xxxx | 亚洲熟妇色xxxxx欧美老妇 | 精品水蜜桃久久久久久久 | v一区无码内射国产 | 中文字幕av无码一区二区三区电影 | 一区二区三区乱码在线 | 欧洲 | 老熟女乱子伦 | 露脸叫床粗话东北少妇 | 色一情一乱一伦一视频免费看 | 亚洲精品一区二区三区在线 | 久久久久99精品成人片 | 色婷婷香蕉在线一区二区 | √8天堂资源地址中文在线 | 国内揄拍国内精品人妻 | 亚洲熟妇色xxxxx亚洲 | 亚洲中文字幕无码一久久区 | 国产精品国产自线拍免费软件 | 精品无码av一区二区三区 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产一区二区三区日韩精品 | 玩弄人妻少妇500系列视频 | 国产精品久久久久久亚洲影视内衣 | 色婷婷久久一区二区三区麻豆 | 麻花豆传媒剧国产免费mv在线 | 狠狠cao日日穞夜夜穞av | 欧美喷潮久久久xxxxx | 真人与拘做受免费视频一 | 97夜夜澡人人爽人人喊中国片 | 一本色道久久综合亚洲精品不卡 | 国产情侣作爱视频免费观看 | 国产99久久精品一区二区 | 性色欲情网站iwww九文堂 | 全球成人中文在线 | 99久久精品无码一区二区毛片 | 国产内射老熟女aaaa | 亚洲自偷精品视频自拍 | 国产精品亚洲综合色区韩国 | 丰满岳乱妇在线观看中字无码 | 亚洲精品久久久久avwww潮水 | 国精产品一品二品国精品69xx | 精品厕所偷拍各类美女tp嘘嘘 | 免费无码的av片在线观看 | 两性色午夜视频免费播放 | 亚洲国产精品无码一区二区三区 | 国产精品无码永久免费888 | 午夜理论片yy44880影院 | 亚洲国产欧美日韩精品一区二区三区 | 欧美国产日产一区二区 | 色综合久久中文娱乐网 | 亚洲爆乳大丰满无码专区 | 久久亚洲中文字幕精品一区 | 乱人伦人妻中文字幕无码久久网 | 永久免费精品精品永久-夜色 | 国产情侣作爱视频免费观看 | 纯爱无遮挡h肉动漫在线播放 | 好男人社区资源 | 婷婷色婷婷开心五月四房播播 | 精品人妻人人做人人爽夜夜爽 | 日本爽爽爽爽爽爽在线观看免 | 精品日本一区二区三区在线观看 | 国产精品久久久久无码av色戒 | 精品水蜜桃久久久久久久 | 亚洲午夜福利在线观看 | 国产精品自产拍在线观看 | 久久久久久av无码免费看大片 | 激情人妻另类人妻伦 | 一本久久a久久精品vr综合 | 国产成人人人97超碰超爽8 | 丰满诱人的人妻3 | 欧美性生交xxxxx久久久 | 精品久久久久久亚洲精品 | 性欧美大战久久久久久久 | 亚洲人成网站色7799 | 亚洲欧美日韩综合久久久 | 一本久久伊人热热精品中文字幕 | 久久99精品久久久久婷婷 | 我要看www免费看插插视频 | 国产两女互慰高潮视频在线观看 | 国产精品亚洲五月天高清 | 日本熟妇人妻xxxxx人hd | av香港经典三级级 在线 | 精品人妻av区 | 色综合久久久无码网中文 | 成人性做爰aaa片免费看 | 国内综合精品午夜久久资源 | 无码av免费一区二区三区试看 | 无码国产激情在线观看 | 亚洲理论电影在线观看 | 狂野欧美激情性xxxx | 亚洲aⅴ无码成人网站国产app | 亚洲经典千人经典日产 | 成人免费无码大片a毛片 | 一本加勒比波多野结衣 | 精品亚洲韩国一区二区三区 | 欧美性猛交内射兽交老熟妇 | 午夜免费福利小电影 | 老熟女重囗味hdxx69 | 久久久久久国产精品无码下载 | 任你躁国产自任一区二区三区 | 4hu四虎永久在线观看 | 日韩精品久久久肉伦网站 | 内射老妇bbwx0c0ck | 亚洲自偷精品视频自拍 | 国内精品久久久久久中文字幕 | 东京一本一道一二三区 | 曰韩无码二三区中文字幕 | 人妻天天爽夜夜爽一区二区 | 熟妇女人妻丰满少妇中文字幕 | 亚洲色偷偷偷综合网 | 国产成人精品无码播放 | 小鲜肉自慰网站xnxx | 97久久国产亚洲精品超碰热 | 无套内谢的新婚少妇国语播放 | 亚洲一区av无码专区在线观看 | 成人一在线视频日韩国产 | 人妻少妇精品久久 | 无码人妻少妇伦在线电影 | 55夜色66夜色国产精品视频 | 亚洲熟妇色xxxxx亚洲 | 成人精品天堂一区二区三区 | 国产情侣作爱视频免费观看 | 精品一区二区三区无码免费视频 | 久久久久国色av免费观看性色 | 亚洲娇小与黑人巨大交 | 麻豆精产国品 | 人人妻人人澡人人爽人人精品 | 性史性农村dvd毛片 | 久久人人爽人人爽人人片ⅴ | 99久久99久久免费精品蜜桃 | 伊人色综合久久天天小片 | 久久亚洲国产成人精品性色 | 久久久www成人免费毛片 | 国精产品一品二品国精品69xx | 亚洲中文字幕乱码av波多ji | 荡女精品导航 | 露脸叫床粗话东北少妇 | 性啪啪chinese东北女人 | 狠狠cao日日穞夜夜穞av | 高中生自慰www网站 | 精品欧洲av无码一区二区三区 | 国产熟妇高潮叫床视频播放 | 影音先锋中文字幕无码 | a片在线免费观看 | 1000部夫妻午夜免费 | 亚洲国产欧美日韩精品一区二区三区 | 免费看男女做好爽好硬视频 | 国产真实夫妇视频 | av小次郎收藏 | 中文字幕中文有码在线 | 夫妻免费无码v看片 | 日本精品少妇一区二区三区 | 3d动漫精品啪啪一区二区中 | 高清不卡一区二区三区 | 亚洲男人av天堂午夜在 | 久久人人97超碰a片精品 | 中文字幕乱码亚洲无线三区 | 精品国产精品久久一区免费式 | 亚洲中文字幕无码一久久区 | 国产乱码精品一品二品 | 国产午夜视频在线观看 | 荫蒂被男人添的好舒服爽免费视频 | 欧美日韩一区二区免费视频 | 天堂亚洲2017在线观看 | 欧美亚洲国产一区二区三区 | 精品一区二区三区波多野结衣 | 国产精品成人av在线观看 | 色欲av亚洲一区无码少妇 | 免费播放一区二区三区 | 一个人免费观看的www视频 | 国产又粗又硬又大爽黄老大爷视 | 国产色视频一区二区三区 | 香蕉久久久久久av成人 | 久久天天躁夜夜躁狠狠 | 色一情一乱一伦 | 亚洲精品中文字幕 | 亚洲 高清 成人 动漫 | 99久久久无码国产aaa精品 | 无码成人精品区在线观看 | 东京热男人av天堂 | 久久精品国产99久久6动漫 | 玩弄人妻少妇500系列视频 | 欧美野外疯狂做受xxxx高潮 | 欧美成人午夜精品久久久 | 性欧美牲交xxxxx视频 | 国产av一区二区三区最新精品 | 亚洲欧美日韩综合久久久 | 亚洲日本va午夜在线电影 | 亚洲午夜无码久久 | 亚洲欧美日韩成人高清在线一区 | 久久综合激激的五月天 | 4hu四虎永久在线观看 | 日产国产精品亚洲系列 | www一区二区www免费 | 强辱丰满人妻hd中文字幕 | 国产精品无码成人午夜电影 | 久久久久久久久蜜桃 | 亚洲日本在线电影 | 午夜福利一区二区三区在线观看 | 国产69精品久久久久app下载 | 日本熟妇乱子伦xxxx | 欧美午夜特黄aaaaaa片 | 亚洲精品一区二区三区在线观看 | 成人女人看片免费视频放人 | 久久久久99精品国产片 | aⅴ亚洲 日韩 色 图网站 播放 | 久久久久av无码免费网 | 亚洲国产精品一区二区美利坚 | 在线欧美精品一区二区三区 | 99久久久无码国产精品免费 | 午夜熟女插插xx免费视频 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产成人无码一二三区视频 | 特级做a爰片毛片免费69 | 久久伊人色av天堂九九小黄鸭 | 高潮毛片无遮挡高清免费视频 | 国产精品久久久久9999小说 | 日本一区二区三区免费高清 | 亚洲国产精品一区二区美利坚 | 国产精品va在线观看无码 | 亚洲乱码国产乱码精品精 | 性做久久久久久久久 | 午夜成人1000部免费视频 | 亚洲欧洲日本综合aⅴ在线 | 国精产品一区二区三区 | 亚洲色欲久久久综合网东京热 | 精品偷自拍另类在线观看 | 午夜成人1000部免费视频 | 久久久精品456亚洲影院 | 欧美日本精品一区二区三区 | 亚洲区小说区激情区图片区 | 麻豆md0077饥渴少妇 | 精品无码av一区二区三区 | 亚洲中文字幕无码中字 | 超碰97人人做人人爱少妇 | 丰满诱人的人妻3 | 国内精品人妻无码久久久影院 | 日韩精品无码一区二区中文字幕 | 曰韩无码二三区中文字幕 | 亚洲小说春色综合另类 | 内射爽无广熟女亚洲 | 一本色道婷婷久久欧美 | 俺去俺来也www色官网 | 色婷婷综合中文久久一本 | 亚洲精品午夜无码电影网 | 国模大胆一区二区三区 | 夫妻免费无码v看片 | 欧洲vodafone精品性 | 精品亚洲成av人在线观看 | 人妻夜夜爽天天爽三区 | 久在线观看福利视频 | 男女下面进入的视频免费午夜 | 亚洲日韩av片在线观看 | 国产人成高清在线视频99最全资源 | 亚洲欧美综合区丁香五月小说 | 又大又黄又粗又爽的免费视频 | 国产在线精品一区二区高清不卡 | 亚洲一区二区三区在线观看网站 | 激情亚洲一区国产精品 | 亚洲伊人久久精品影院 | 无码纯肉视频在线观看 | 一本大道久久东京热无码av | 亚洲成av人在线观看网址 | 日本在线高清不卡免费播放 | 精品偷自拍另类在线观看 | 亚洲精品久久久久中文第一幕 | 丁香花在线影院观看在线播放 | 黑人玩弄人妻中文在线 | 亚洲经典千人经典日产 | 内射老妇bbwx0c0ck | 亚洲一区二区三区四区 | 中文字幕无码日韩专区 | 国产成人无码av一区二区 | 日韩无套无码精品 | 国产精品无码久久av | 国产乱人偷精品人妻a片 | 久久精品丝袜高跟鞋 | 97se亚洲精品一区 | 疯狂三人交性欧美 | 香港三级日本三级妇三级 | 丁香花在线影院观看在线播放 | 扒开双腿吃奶呻吟做受视频 | 精品无码一区二区三区的天堂 | 一区二区三区乱码在线 | 欧洲 | 国产av人人夜夜澡人人爽麻豆 | 久久久av男人的天堂 | 国产精品自产拍在线观看 | 久久综合色之久久综合 | 无码中文字幕色专区 | 久久久亚洲欧洲日产国码αv | 色情久久久av熟女人妻网站 | 两性色午夜免费视频 | 亚洲国产日韩a在线播放 | 18禁止看的免费污网站 | 日本精品人妻无码免费大全 | 久久99精品国产麻豆蜜芽 | 在线精品国产一区二区三区 | 漂亮人妻洗澡被公强 日日躁 | 久久精品丝袜高跟鞋 | 久久综合网欧美色妞网 | 少妇愉情理伦片bd | 亚洲经典千人经典日产 | 国产午夜福利亚洲第一 | 欧美激情一区二区三区成人 | 美女黄网站人色视频免费国产 | 中文字幕乱码亚洲无线三区 | 四虎影视成人永久免费观看视频 | 日日橹狠狠爱欧美视频 | 88国产精品欧美一区二区三区 | 精品国产aⅴ无码一区二区 | 久久亚洲精品成人无码 | a在线观看免费网站大全 | 久久午夜夜伦鲁鲁片无码免费 | 黑人粗大猛烈进出高潮视频 | 久久精品中文字幕大胸 | 一本久久a久久精品vr综合 | 国产乡下妇女做爰 | 国内揄拍国内精品少妇国语 | 无码国产色欲xxxxx视频 | 一本久道久久综合狠狠爱 | 久久久精品国产sm最大网站 | 荫蒂被男人添的好舒服爽免费视频 | 熟妇人妻无码xxx视频 | 日本一本二本三区免费 | 人妻天天爽夜夜爽一区二区 | 亚洲欧美精品伊人久久 | 日日麻批免费40分钟无码 | 国产精品无码成人午夜电影 | 欧美日韩一区二区免费视频 | 无遮无挡爽爽免费视频 | 日本欧美一区二区三区乱码 | 青青草原综合久久大伊人精品 | 女人高潮内射99精品 | 国产高清不卡无码视频 | а√资源新版在线天堂 | 国产精品永久免费视频 | 乌克兰少妇性做爰 | 精品国精品国产自在久国产87 | 女人被男人爽到呻吟的视频 | 免费无码肉片在线观看 | 强辱丰满人妻hd中文字幕 | 人妻中文无码久热丝袜 | 精品人妻人人做人人爽夜夜爽 | 粉嫩少妇内射浓精videos | 久久人人爽人人爽人人片av高清 | 波多野结衣一区二区三区av免费 | 国产无遮挡吃胸膜奶免费看 | 蜜桃视频韩日免费播放 | 波多野结衣av一区二区全免费观看 | 在线观看国产一区二区三区 | 国产激情无码一区二区 | 国内少妇偷人精品视频 | av在线亚洲欧洲日产一区二区 | 午夜精品久久久久久久 | 日韩少妇白浆无码系列 | 无码精品人妻一区二区三区av | 国产精品久久久久久久影院 | 久久精品中文字幕一区 | 欧美高清在线精品一区 | 精品久久久久久人妻无码中文字幕 | 一本大道伊人av久久综合 | 日本一区二区三区免费高清 | 亚洲成av人片天堂网无码】 | 97精品人妻一区二区三区香蕉 | 无码人妻丰满熟妇区五十路百度 | 六月丁香婷婷色狠狠久久 | 内射老妇bbwx0c0ck | 久久人人爽人人爽人人片av高清 | 在线播放亚洲第一字幕 | 日日鲁鲁鲁夜夜爽爽狠狠 | 国产精品鲁鲁鲁 | 欧美 亚洲 国产 另类 | 国产精华av午夜在线观看 | 亚洲色成人中文字幕网站 | 青草青草久热国产精品 | 久久精品人人做人人综合试看 | 久久无码中文字幕免费影院蜜桃 | 欧美熟妇另类久久久久久不卡 | 久久无码中文字幕免费影院蜜桃 | 国产精品第一区揄拍无码 | 亚洲欧美国产精品久久 | 国产黄在线观看免费观看不卡 | 久久久久久久久蜜桃 | 久久精品中文字幕大胸 | 精品无码国产自产拍在线观看蜜 | 久久国产精品偷任你爽任你 | 欧美国产日韩亚洲中文 | 97精品国产97久久久久久免费 | 激情综合激情五月俺也去 | 无码吃奶揉捏奶头高潮视频 | 少妇一晚三次一区二区三区 | 久久99精品久久久久婷婷 | 中文字幕 人妻熟女 | 精品久久久中文字幕人妻 | 日韩av无码中文无码电影 | 欧美一区二区三区 | 日本护士毛茸茸高潮 | 无码播放一区二区三区 | 美女扒开屁股让男人桶 | 精品夜夜澡人妻无码av蜜桃 | 性欧美牲交xxxxx视频 | 欧美人与物videos另类 | 人人爽人人澡人人高潮 | 国产精品成人av在线观看 | 国内揄拍国内精品人妻 | 午夜理论片yy44880影院 | 性欧美大战久久久久久久 | аⅴ资源天堂资源库在线 | 国产人妻精品一区二区三区不卡 | 强开小婷嫩苞又嫩又紧视频 | 大胆欧美熟妇xx | 纯爱无遮挡h肉动漫在线播放 | 久久人人爽人人爽人人片av高清 | 国产精品久免费的黄网站 | 国产成人一区二区三区在线观看 | 狠狠色色综合网站 | 性做久久久久久久久 | 国产在热线精品视频 | 国产亚洲美女精品久久久2020 | 人人妻在人人 | 中文字幕乱妇无码av在线 | 日本一卡2卡3卡四卡精品网站 | 国产真人无遮挡作爱免费视频 | 男女作爱免费网站 | 中文字幕+乱码+中文字幕一区 | 欧洲精品码一区二区三区免费看 | 亚洲日韩av一区二区三区中文 | 日日橹狠狠爱欧美视频 | 高清无码午夜福利视频 | 无码帝国www无码专区色综合 | 亚洲色成人中文字幕网站 | 国产在线精品一区二区三区直播 | 男人扒开女人内裤强吻桶进去 | www一区二区www免费 | 国产精品毛片一区二区 | 大屁股大乳丰满人妻 | 人妻少妇精品无码专区二区 | 性生交大片免费看女人按摩摩 | 中文字幕人妻无码一区二区三区 | 日本va欧美va欧美va精品 | 国产内射爽爽大片视频社区在线 | 国产suv精品一区二区五 | 国产成人亚洲综合无码 | 中文亚洲成a人片在线观看 | 国产区女主播在线观看 | 亚洲精品国偷拍自产在线麻豆 | 少妇高潮喷潮久久久影院 | 国产精品无套呻吟在线 | 亚洲精品久久久久中文第一幕 | 日本精品少妇一区二区三区 | 两性色午夜视频免费播放 | 国产深夜福利视频在线 | 亚洲精品久久久久avwww潮水 | 国产精品人人妻人人爽 | www国产亚洲精品久久久日本 | 高中生自慰www网站 | 波多野结衣一区二区三区av免费 | 国产人妻人伦精品 | 国产成人精品无码播放 | 国产精品丝袜黑色高跟鞋 | 日本一本二本三区免费 | 精品一区二区三区无码免费视频 | a国产一区二区免费入口 | 午夜福利试看120秒体验区 | 国产精品久久久久久久影院 | 成 人影片 免费观看 | 1000部夫妻午夜免费 | 国产成人综合美国十次 | 亚洲成av人片在线观看无码不卡 | 精品人妻中文字幕有码在线 | 波多野结衣高清一区二区三区 | 久久五月精品中文字幕 | 亚洲精品一区三区三区在线观看 | 精品人妻中文字幕有码在线 | 国产性生大片免费观看性 | 又湿又紧又大又爽a视频国产 | 国产成人综合美国十次 | 东北女人啪啪对白 | 亚洲成av人在线观看网址 | 精品国产乱码久久久久乱码 | 强开小婷嫩苞又嫩又紧视频 | 免费视频欧美无人区码 | 国产精品毛多多水多 | 色综合久久久无码网中文 | 久久久久久久久蜜桃 | 欧美三级a做爰在线观看 | 欧美xxxx黑人又粗又长 | 老司机亚洲精品影院 | 99久久精品国产一区二区蜜芽 | 国产精品国产三级国产专播 | 亚洲国产午夜精品理论片 | 色狠狠av一区二区三区 | 欧美日韩一区二区免费视频 | 日韩成人一区二区三区在线观看 | 无码精品国产va在线观看dvd | 亚洲一区二区三区香蕉 | 精品人人妻人人澡人人爽人人 | 亚洲综合在线一区二区三区 | 任你躁在线精品免费 | 99国产欧美久久久精品 | 色一情一乱一伦一视频免费看 | 欧美freesex黑人又粗又大 | a片免费视频在线观看 | 亚洲春色在线视频 | 麻豆国产97在线 | 欧洲 | 水蜜桃亚洲一二三四在线 | 亚洲精品欧美二区三区中文字幕 | 婷婷色婷婷开心五月四房播播 | 国产精品嫩草久久久久 | 少妇性l交大片欧洲热妇乱xxx | 国产高潮视频在线观看 | 国内少妇偷人精品视频 | 欧美三级不卡在线观看 | 无码午夜成人1000部免费视频 | 午夜男女很黄的视频 | av无码电影一区二区三区 | 夜夜影院未满十八勿进 | 国产精品手机免费 | 丰满少妇熟乱xxxxx视频 | 麻豆av传媒蜜桃天美传媒 | 亚洲精品一区二区三区在线观看 | 欧美freesex黑人又粗又大 | 亚洲欧美精品aaaaaa片 | 国产成人无码av片在线观看不卡 | 亚洲狠狠婷婷综合久久 | 波多野结衣高清一区二区三区 | 性色av无码免费一区二区三区 | 黑人巨大精品欧美黑寡妇 | 欧美激情内射喷水高潮 | 99久久精品无码一区二区毛片 | 欧美放荡的少妇 | 国产内射老熟女aaaa | 久久精品国产大片免费观看 | 美女毛片一区二区三区四区 | 精品偷自拍另类在线观看 | 熟女少妇人妻中文字幕 | 亚洲娇小与黑人巨大交 | 亚洲国产精品久久久久久 | 国产精品人人妻人人爽 | 国产高清av在线播放 | 亚洲欧美日韩综合久久久 | 亚洲国产高清在线观看视频 | 免费视频欧美无人区码 | 欧美日韩一区二区综合 | 亚洲成色www久久网站 | 狠狠色色综合网站 | 在线观看免费人成视频 | 国产 浪潮av性色四虎 | 欧美人与禽zoz0性伦交 | 精品夜夜澡人妻无码av蜜桃 | 真人与拘做受免费视频 | 国产成人一区二区三区在线观看 | 久久天天躁夜夜躁狠狠 | 1000部啪啪未满十八勿入下载 | 久久久久久久久蜜桃 | 又粗又大又硬又长又爽 | 十八禁视频网站在线观看 | 国产人妖乱国产精品人妖 | 无码中文字幕色专区 | 国语精品一区二区三区 | 久久综合久久自在自线精品自 | 亚洲日韩精品欧美一区二区 | 国产亚洲视频中文字幕97精品 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 亚拍精品一区二区三区探花 | 国产xxx69麻豆国语对白 | 国产无遮挡又黄又爽免费视频 | 国产97在线 | 亚洲 | 国产精品爱久久久久久久 | 呦交小u女精品视频 | 亚洲の无码国产の无码步美 | 日本一卡二卡不卡视频查询 | 国产午夜手机精彩视频 | 一本一道久久综合久久 | 熟女俱乐部五十路六十路av | 青青草原综合久久大伊人精品 | 搡女人真爽免费视频大全 | 特级做a爰片毛片免费69 | 色欲综合久久中文字幕网 | 亚洲一区二区三区播放 | 国产超碰人人爽人人做人人添 | 国产成人综合在线女婷五月99播放 | 在线视频网站www色 | 一区二区三区高清视频一 | 大胆欧美熟妇xx | 中文毛片无遮挡高清免费 | 国模大胆一区二区三区 | 两性色午夜视频免费播放 | 天天综合网天天综合色 | 免费无码的av片在线观看 | 国产成人综合美国十次 | 亚洲一区二区三区在线观看网站 | 亚洲中文字幕在线无码一区二区 | 在线精品国产一区二区三区 | 小泽玛莉亚一区二区视频在线 | 婷婷综合久久中文字幕蜜桃三电影 | 国产精品无码一区二区桃花视频 | 成年美女黄网站色大免费视频 | 亚洲日韩中文字幕在线播放 | 六十路熟妇乱子伦 | ass日本丰满熟妇pics | 久久久久久a亚洲欧洲av冫 | 国产精品沙发午睡系列 | 亚洲色偷偷偷综合网 | 99久久人妻精品免费二区 | 亚洲综合无码久久精品综合 | 国产在线aaa片一区二区99 | 日韩精品a片一区二区三区妖精 | 亚洲综合色区中文字幕 | 娇妻被黑人粗大高潮白浆 | 日韩精品成人一区二区三区 | 成人欧美一区二区三区黑人免费 | 黑人巨大精品欧美黑寡妇 | 精品国产一区二区三区四区在线看 | 国色天香社区在线视频 | 国产成人一区二区三区在线观看 | 亚洲中文字幕在线无码一区二区 | 图片区 小说区 区 亚洲五月 | 图片区 小说区 区 亚洲五月 | 国产av一区二区三区最新精品 | 成年美女黄网站色大免费视频 | 任你躁在线精品免费 | 欧美老妇与禽交 | 国产亚洲美女精品久久久2020 | 99久久99久久免费精品蜜桃 | 亚洲 日韩 欧美 成人 在线观看 | 黑森林福利视频导航 | 国产超碰人人爽人人做人人添 | 无码人妻丰满熟妇区五十路百度 | 亚洲精品无码人妻无码 | 牛和人交xxxx欧美 | 少妇被粗大的猛进出69影院 | 亚洲精品久久久久avwww潮水 | 日本精品人妻无码免费大全 | 中文字幕 人妻熟女 | 成人免费视频一区二区 | 国产明星裸体无码xxxx视频 | 久久久精品456亚洲影院 | 久精品国产欧美亚洲色aⅴ大片 | 99re在线播放 | 国产成人综合在线女婷五月99播放 | 午夜福利一区二区三区在线观看 | 欧美 丝袜 自拍 制服 另类 | 高清无码午夜福利视频 | 鲁鲁鲁爽爽爽在线视频观看 | 永久免费观看国产裸体美女 | 精品国产一区二区三区av 性色 | 性欧美videos高清精品 | 日韩人妻无码一区二区三区久久99 | 中文字幕无码av波多野吉衣 | 精品人妻人人做人人爽夜夜爽 | 欧美性生交活xxxxxdddd | 久久综合给久久狠狠97色 | 久久97精品久久久久久久不卡 | 久久久久成人片免费观看蜜芽 | 在线观看欧美一区二区三区 | 亚洲国产精品一区二区第一页 | 久久久久久久久蜜桃 | 亚洲人成网站免费播放 | 18精品久久久无码午夜福利 | 老熟妇乱子伦牲交视频 | 国产美女极度色诱视频www | 国产色视频一区二区三区 | 色噜噜亚洲男人的天堂 | 亚洲一区二区三区在线观看网站 | 国产精品鲁鲁鲁 | 亚洲国产精品无码一区二区三区 | 在线成人www免费观看视频 | 夜精品a片一区二区三区无码白浆 | 久久久精品国产sm最大网站 | 人人妻人人澡人人爽欧美一区九九 | 一本加勒比波多野结衣 | 成年美女黄网站色大免费视频 | 国产乱人偷精品人妻a片 | 久久精品中文字幕大胸 | 女人被男人躁得好爽免费视频 | 欧美亚洲国产一区二区三区 | 午夜丰满少妇性开放视频 | 国产成人精品久久亚洲高清不卡 | 亚洲精品美女久久久久久久 | 精品欧洲av无码一区二区三区 | 99久久无码一区人妻 | 思思久久99热只有频精品66 | 老太婆性杂交欧美肥老太 | 88国产精品欧美一区二区三区 | 国产色在线 | 国产 | 99国产精品白浆在线观看免费 | 妺妺窝人体色www在线小说 | 精品厕所偷拍各类美女tp嘘嘘 | 日韩人妻无码一区二区三区久久99 | 欧美老妇交乱视频在线观看 | 久久久久久久人妻无码中文字幕爆 | 久久国产精品二国产精品 | 亚洲а∨天堂久久精品2021 | 久久综合激激的五月天 | 精品一区二区三区无码免费视频 | 天堂无码人妻精品一区二区三区 | 国产超碰人人爽人人做人人添 | 老熟妇乱子伦牲交视频 | 人妻少妇精品无码专区动漫 | 亚洲国精产品一二二线 | 国产精品久久久久影院嫩草 | 又紧又大又爽精品一区二区 | 大地资源网第二页免费观看 | 久久视频在线观看精品 | 日日摸天天摸爽爽狠狠97 | 扒开双腿吃奶呻吟做受视频 | 久久人人97超碰a片精品 | 波多野结衣av一区二区全免费观看 | 国产精品自产拍在线观看 | 欧美日韩色另类综合 | 亚洲一区二区三区国产精华液 | 婷婷六月久久综合丁香 | 亚洲男人av香蕉爽爽爽爽 | 伊人久久婷婷五月综合97色 | 男女爱爱好爽视频免费看 | 天天拍夜夜添久久精品大 | 无码午夜成人1000部免费视频 | 男女猛烈xx00免费视频试看 | 亚洲一区二区三区无码久久 | 亚洲 激情 小说 另类 欧美 | 老子影院午夜伦不卡 | 无码av免费一区二区三区试看 | 无码av最新清无码专区吞精 | 美女扒开屁股让男人桶 | 亚洲一区二区三区播放 | 亚洲狠狠婷婷综合久久 | 久久久久久久人妻无码中文字幕爆 | 丰满少妇熟乱xxxxx视频 | 亚洲乱码国产乱码精品精 | 国产特级毛片aaaaaaa高清 | 欧美日韩人成综合在线播放 | 成人免费视频视频在线观看 免费 | 中文无码精品a∨在线观看不卡 | 最新版天堂资源中文官网 | 精品乱码久久久久久久 | 欧洲精品码一区二区三区免费看 | 99视频精品全部免费免费观看 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 桃花色综合影院 | 亚洲一区二区三区国产精华液 | 未满小14洗澡无码视频网站 | 又黄又爽又色的视频 | 精品国偷自产在线 | 亚洲国产欧美日韩精品一区二区三区 | 天堂无码人妻精品一区二区三区 | 强辱丰满人妻hd中文字幕 | ass日本丰满熟妇pics | 亚拍精品一区二区三区探花 | 欧美性生交活xxxxxdddd | 成人精品一区二区三区中文字幕 | 人人妻人人澡人人爽人人精品浪潮 | 亚洲欧美色中文字幕在线 | 日韩精品乱码av一区二区 | 亚洲a无码综合a国产av中文 | 国产精品久久久久无码av色戒 | 午夜嘿嘿嘿影院 | 中文精品无码中文字幕无码专区 | 精品无人国产偷自产在线 | 日韩精品无码一区二区中文字幕 | 国产人妻精品一区二区三区 | 国产精品人人爽人人做我的可爱 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产精品二区一区二区aⅴ污介绍 | 成年美女黄网站色大免费视频 | 欧美日韩亚洲国产精品 | 国产av无码专区亚洲a∨毛片 | 久久国产精品二国产精品 | 亚洲成av人片在线观看无码不卡 | 东京热无码av男人的天堂 | 久久久久久亚洲精品a片成人 | 久久精品国产亚洲精品 | 精品国产av色一区二区深夜久久 | 久久久久久九九精品久 | 亚洲精品国产a久久久久久 | 精品成人av一区二区三区 | 欧美日本精品一区二区三区 | 国产精品人人爽人人做我的可爱 | 国产亚av手机在线观看 | 久久97精品久久久久久久不卡 | 国产一区二区三区影院 | 牲欲强的熟妇农村老妇女视频 | 国产色精品久久人妻 | 97人妻精品一区二区三区 | 国产成人无码一二三区视频 | 最近中文2019字幕第二页 | 国产va免费精品观看 | 伊人色综合久久天天小片 | 欧美 丝袜 自拍 制服 另类 | 亚洲精品美女久久久久久久 | 激情五月综合色婷婷一区二区 | 亚洲国产精品无码一区二区三区 | 99久久人妻精品免费一区 | 成人欧美一区二区三区 | 亚洲第一无码av无码专区 | 成熟女人特级毛片www免费 | 小sao货水好多真紧h无码视频 | 色综合久久久久综合一本到桃花网 | 欧美 日韩 亚洲 在线 | 精品无码国产自产拍在线观看蜜 | 国产av一区二区三区最新精品 | a片免费视频在线观看 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产色在线 | 国产 | 国产午夜精品一区二区三区嫩草 | 久久亚洲a片com人成 |