MVC5使用EF6 Code First--創建EF數據模型(一)


此Web應用程序演示如何使用Entity Framework 6和Visual Studio 2015創建ASP.NET MVC 5應用程序。本教程使用“Code First ”即代碼先行。有關如何在“Code First”,“Database First”和“Model First”之間進行選擇,請參閱實體框架開發工作流程。如下:

  • Database First

    如果已經擁有數據庫,Visual Studio中內置的Entity Framework設計器可以自動生成一個數據模型,該模型由對應於現有數據庫對象(如表和列)的類和屬性組成。有關數據庫結構,數據模型及映射之間的信息以XML格式存儲在.edmx文件中。實體框架設計器提供了一個可視化界面,您可以使用它來顯示和編輯.edmx文件。

  • Model First

    如果您還沒有數據庫,則可以使用Visual Studio中的Entity Framework設計器在.edmx文件中創建一個模型。當模型建完后,可以執行.edmx文件來創建數據庫。

  • Code First

    無論您是否擁有數據庫,都可以使用Code First。如果沒有數據庫,可以編寫類和對應於表和列的屬性。如果有數據庫,那么Entity Framework可以生成與現有表和列對應的類和屬性。如果使用Code First創建數據庫,則可以使用“migration(遷移)”來將數據庫部署到生產環境。當數據模型更改時,可以將更改部署到生產環境中,而不改變原有的數據。

Contoso University Web應用程序

此教程中構建的應用程序是一個簡單的web網站。
用戶可以查看和更新學生課程和教師信息。以下是創建的幾個頁面。

創建一個MVC Web應用程序

打開Visual Studio 2015並創建一個名為“EFDemo”的新C# Web項目。

在“ 新建ASP.NET項目”對話框中,選擇MVC模板。

更改身份驗證,改為不進行身份驗證(N)。

單擊“ 確定”創建項目。

做幾個簡單的更改。打開視圖\ Shared \ _Layout.cshtml,並進行以下更改,如下圖出顯示:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 5     <meta charset="utf-8" />
 6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
 7     <title>@ViewBag.Title - Contoso University </title>
 8     @Styles.Render("~/Content/css")
 9     @Scripts.Render("~/bundles/modernizr")
10 </head>
11 <body>
12     <div class="navbar navbar-inverse navbar-fixed-top">
13         <div class="container">
14             <div class="navbar-header">
15                 <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
16                     <span class="icon-bar"></span>
17                     <span class="icon-bar"></span>
18                     <span class="icon-bar"></span>
19                 </button>
20                 @Html.ActionLink("Contoso University ", "Index", "Home", new { area = "" }, new { @class = "navbar-brand" }) 21             </div>
22             <div class="navbar-collapse collapse">
23                 <ul class="nav navbar-nav">
24                     <li>@Html.ActionLink("主頁", "Index", "Home")</li>
25                     <li>@Html.ActionLink("關於", "About", "Home")</li>
26                     <li>@Html.ActionLink("學生", "Index", "Student")</li>
27                     <li>@Html.ActionLink("課程", "Index", "Course")</li>
28                     <li>@Html.ActionLink("老師", "Index", "Instructor")</li>
29                     <li>@Html.ActionLink("部門", "Index", "Department")</li>
30                 </ul>
31             </div>
32         </div>
33     </div>
34     <div class="container body-content">
35         @RenderBody()
36         <hr />
37         <footer>
38             <p>&copy; @DateTime.Now.Year - Contoso University </p>
39         </footer>
40     </div>
41 
42     @Scripts.Render("~/bundles/jquery")
43     @Scripts.Render("~/bundles/bootstrap")
44     @RenderSection("scripts", required: false)
45 </body>
46 </html>

Views \ Home \ Index.cshtml中,使用以下代碼替換原有內容:

 1 @{
 2     ViewBag.Title = "Home Page";
 3 }
 4 
 5 <div class="jumbotron">
 6     <h1>Contoso University </h1>
 7 </div>
 8 <div class="row">
 9     <div class="col-md-4">
10         <h2>Welcome to Contoso University </h2>
11         <p>
12             Contoso University is a sample application that
13             demonstrates how to use Entity Framework 6 in an
14             ASP.NET MVC 5 web application.
15         </p>
16     </div>
17     <div class="col-md-4">
18         <h2>Build it from scratch</h2>
19         <p>You can build the application by following the steps in the tutorial series on the ASP.NET site.</p>
20         <p><a class="btn btn-default" href="http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/">See the tutorial &raquo;</a></p>
21     </div>
22     <div class="col-md-4">
23         <h2>Download it</h2>
24         <p>You can download the completed project from the Microsoft Code Gallery.</p>
25         <p><a class="btn btn-default" href="http://code.msdn.microsoft.com/ASPNET-MVC-Application-b01a9fe8">Download &raquo;</a></p>
26     </div>
27 </div>
\Home\Index.cshtml

CTRL + F5運行網站,顯示如下:

安裝EF6

工具菜單中單擊NuGet包管理器,然后單擊程序包管理器控制台

在“ 管理器管理器”窗口中,輸入以下命令:

Install-Package EntityFramework

第二種方法:項目上右擊選擇管理NuGet程序包,選擇瀏覽輸入EntityFramework搜索,列表就會列出結果,選擇要安裝的包,點擊右側的安裝(我已經安裝過了,所以顯示的是"卸載")

這里顯示安裝的是Entity Framework6.1.3,NuGet將安裝最新版本的Entity Framework(不包括預發行版本)。

創建數據模型

接下來,您將為Contoso University 應用程序創建實體。將從以下三個實體開始:

StudentEnrollment是一對多關系CourseEnrollment也是一對多的關系換句話說,學生可以注冊任何數量的課程,課程可以被任何數量的學生注冊(學生和課程是多對多關系)。

接下來將為每個實體創建一個類。

Student

Models文件夾中,創建一個名為Student.cs的類文件,並使用以下代碼替換模板代碼:

 1 using System;
 2 using System.Collections.Generic;
 3 
 4 namespace EFDemo.Models
 5 {
 6     public class Student
 7     {
 8         public int ID { get; set; }
 9         public string LastName { get; set; }
10         public string FirstMidName { get; set; }
11         public DateTime EnrollmentDate { get; set; }
12         
13         public virtual ICollection<Enrollment> Enrollments { get; set; }
14     }
15 }
Student.cs

ID屬性將成為數據庫表的主鍵列。默認情況下,Entity Framework將一個名為IDclassnameID的屬性作為主鍵。

該 Enrollments屬性是導航屬性導航屬性包含與該實體相關的其他實體信息。在這種情況下,Enrollments持有與該Student實體相關的Enrollment實體的所有信息。

導航屬性通常被定義為virtual使得它們可以利用某些實體框架功能,例如延遲加載

如果導航屬性包含多個實體(如多對多或一對多關系),則其類型必須是list集合,例如ICollection

Enrollment

Models文件夾中,創建Enrollment.cs並使用以下代碼替換現有代碼:

 1 namespace EFDemo.Models
 2 {
 3     public enum Grade
 4     {
 5         A, B, C, D, F
 6     }
 7 
 8     public class Enrollment
 9     {
10         public int EnrollmentID { get; set; }
11         public int CourseID { get; set; }
12         public int StudentID { get; set; }
13         public Grade? Grade { get; set; }
14         
15         public virtual Course Course { get; set; }
16         public virtual Student Student { get; set; }
17     }
18 }
Enrollment.cs

該EnrollmentID屬性是主鍵; 該實體主鍵使用類名 加ID的命名方式,而不是直接使用ID通常會選擇一種固定的命名方式,並在所有數據模型中使用。在這里,可以使用任意命名方式。在后面的教程中,將看到如何使用ID,而不用classnameID,這樣更容易在數據模型中實現繼承。

Grade屬性是一個枚舉類型Grade類型后的問號表示該Grade屬性可以為空空值表示未知等級或尚未分配。

StudentID屬性是一個外鍵,以及相應的導航屬性Student一個Enrollment實體與一個Student實體相關聯,因此該屬性只能保存一個Student實體

CourseID屬性也是一個外鍵,以及相應的導航屬性Course一個Enrollment實體與一個Course實體相關聯

Course

Models文件夾中,創建Course.cs,使用以下代碼替換模板代碼: 

 1 using System.Collections.Generic;
 2 using System.ComponentModel.DataAnnotations.Schema;
 3 
 4 namespace EFDemo.Models
 5 {
 6     public class Course
 7     {
 8         [DatabaseGenerated(DatabaseGeneratedOption.None)]
 9         public int CourseID { get; set; }
10         public string Title { get; set; }
11         public int Credits { get; set; }
12         
13         public virtual ICollection<Enrollment> Enrollments { get; set; }
14     }
15 }
Course.cs

Enrollments屬性是導航屬性。一個Course實體可以有任意數量的Enrollment實體。

DatabaseGenerated屬性,DatabaseGeneratedOption.None 設置允許輸入課程主鍵,而不是讓數據庫自動生成它(不是自動增長)。

創建數據庫上下文

右鍵單擊該項目解決方案資源管理器,然后單擊新建文件夾。命名新文件夾DAL(用於數據訪問層)。在該文件夾中創建一個名為SchoolContext.cs的類,代碼如下:

 1 using EFDemo.Models;
 2 using System.Data.Entity;
 3 using System.Data.Entity.ModelConfiguration.Conventions;
 4 
 5 namespace EFDemo.DAL
 6 {
 7     public class SchoolContext : DbContext
 8     {
 9         public SchoolContext() : base("SchoolDbContext")
10         {
11 
12         }
13 
14         public DbSet<Student> Students { get; set; }
15         public DbSet<Enrollment> Enrollments { get; set; }
16         public DbSet<Course> Courses { get; set; }
17 
18         protected override void OnModelCreating(DbModelBuilder modelBuilder)
19         {
20             //阻止表名復數形式
21             modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
22         }
23     }
24 }
SchoolContext.cs

指定連接字符串

連接字符串的名稱傳遞給構造函數

1 public SchoolContext() : base("SchoolDbContext")
2 {
3 }

Web.config文件中連接字符串如以下所示:

1  <connectionStrings>
2        <add name="SchoolDbContext" providerName="System.Data.SqlClient" connectionString="Data Source=ServerName;Initial Catalog=DatabaseName;Integrated Security=False;User Id=userid;Password=password;MultipleActiveResultSets=True" />
3    </connectionStrings>

也可以傳遞連接字符串本身,而不是存儲在Web.config文件中。

如果不指定連接字符串或顯式指定名稱,則Entity Framework假定連接字符串名稱與類名稱相同。

指定實體集DbSet<>

每個實體集創建一個DbSet屬性。在EF中,實體集對應於數據庫的表,實體對應於表中的一行。

注意:可以省略聲明DbSet<Enrollment>DbSet<Course>,它們將正常工作。EF將默認隱式地包含它們。

指定單數表名

OnModelCreating 方法中modelBuilder.Conventions.Remove語句阻止表名的復數形式。如果不這樣做,在數據庫中生成的表將被命名為復數形式(Students)。

設置使用測試數據來初始化數據庫

EF可以在應用程序運行時(或者當模型與現有數據庫不同步時)自動創建(或刪除或重新創建)數據庫。還可以編寫一個 Seed 方法,EF將在創建數據庫后自動調用,以便添加測試數據。

EF默認的是在數據庫不存在(CreateDatabaseIfNotExists)時創建數據庫(如果模型已更改,數據庫已經存在),則拋出異常。在本章中,將指定每當模型改變時,才刪除和重新創建數據庫。刪除和重新創建數據庫會丟失數據庫中原先的所有數據。這通常只在開發過程中使用,因為Seed方法將在數據庫重新創建時才運行,並重新添加測試數據。但在生產中環境,不可能每次更改數據庫時丟失所有數據。在下面的章節,將學習如何通過使用Code First  migration(遷移)來更改數據庫,而不影響原來的數據。


 CreateDatabaseIfNotExists

這是默認的數據庫初始化類,除非手動指定其他類。顧名思義,CreateDatabaseIfNotExists類僅在不存在數據庫時創建數據庫。

DropCreateDatabaseIfModelChanges

只要當模型類和表之間不匹配時,就會刪除數據庫並重新創建它。

DropCreateDatabaseAlways

每次運行應用程序時,都將刪除並重新創建數據庫,而不管它是否已經存在。


 在DAL文件夾中,創建一個名為SchoolInitializer.cs的類,代碼如下:

 1 using EFDemo.Models;
 2 using System;
 3 using System.Collections.Generic;
 4 using System.Data.Entity;
 5 
 6 namespace EFDemo.DAL
 7 {
 8     public class SchoolInitializer : DropCreateDatabaseIfModelChanges<SchoolContext>
 9     {
10         protected override void Seed(SchoolContext context)
11         {
12             var students = new List<Student>
13             {
14             new Student{FirstMidName="Carson",LastName="Alexander",EnrollmentDate=DateTime.Parse("2005-09-01")},
15             new Student{FirstMidName="Meredith",LastName="Alonso",EnrollmentDate=DateTime.Parse("2002-09-01")},
16             new Student{FirstMidName="Arturo",LastName="Anand",EnrollmentDate=DateTime.Parse("2003-09-01")},
17             new Student{FirstMidName="Gytis",LastName="Barzdukas",EnrollmentDate=DateTime.Parse("2002-09-01")},
18             new Student{FirstMidName="Yan",LastName="Li",EnrollmentDate=DateTime.Parse("2002-09-01")},
19             new Student{FirstMidName="Peggy",LastName="Justice",EnrollmentDate=DateTime.Parse("2001-09-01")},
20             new Student{FirstMidName="Laura",LastName="Norman",EnrollmentDate=DateTime.Parse("2003-09-01")},
21             new Student{FirstMidName="Nino",LastName="Olivetto",EnrollmentDate=DateTime.Parse("2005-09-01")}
22             };
23             students.ForEach(s => context.Students.Add(s));
24             context.SaveChanges();
25 
26             var courses = new List<Course>
27             {
28             new Course{CourseID=1050,Title="Chemistry",Credits=3,},
29             new Course{CourseID=4022,Title="Microeconomics",Credits=3,},
30             new Course{CourseID=4041,Title="Macroeconomics",Credits=3,},
31             new Course{CourseID=1045,Title="Calculus",Credits=4,},
32             new Course{CourseID=3141,Title="Trigonometry",Credits=4,},
33             new Course{CourseID=2021,Title="Composition",Credits=3,},
34             new Course{CourseID=2042,Title="Literature",Credits=4,}
35             };
36             courses.ForEach(s => context.Courses.Add(s));
37             context.SaveChanges();
38 
39             var enrollments = new List<Enrollment>
40             {
41             new Enrollment{StudentID=1,CourseID=1050,Grade=Grade.A},
42             new Enrollment{StudentID=1,CourseID=4022,Grade=Grade.C},
43             new Enrollment{StudentID=1,CourseID=4041,Grade=Grade.B},
44             new Enrollment{StudentID=2,CourseID=1045,Grade=Grade.B},
45             new Enrollment{StudentID=2,CourseID=3141,Grade=Grade.F},
46             new Enrollment{StudentID=2,CourseID=2021,Grade=Grade.F},
47             new Enrollment{StudentID=3,CourseID=1050},
48             new Enrollment{StudentID=4,CourseID=1050,},
49             new Enrollment{StudentID=4,CourseID=4022,Grade=Grade.F},
50             new Enrollment{StudentID=5,CourseID=4041,Grade=Grade.C},
51             new Enrollment{StudentID=6,CourseID=1045},
52             new Enrollment{StudentID=7,CourseID=3141,Grade=Grade.A},
53             };
54             enrollments.ForEach(s => context.Enrollments.Add(s));
55             context.SaveChanges();
56         }
57     }
58 }
SchoolInitializer.cs

該Seed方法用於添加測試數據。

指定數據庫初始化程序

打開Web.config文件,添加代碼如下: 

 1 <entityFramework>
 2 
 3     <contexts>
 4       <context type="EFDemo.DAL.SchoolContext, EFDemo">
 5         <databaseInitializer type="EFDemo.DAL.SchoolInitializer, EFDemo" />
 6       </context>
 7     </contexts>
 8 
 9     <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
10       <parameters>
11         <parameter value="mssqllocaldb" />
12       </parameters>
13     </defaultConnectionFactory>
14     <providers>
15       <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
16     </providers>
17   </entityFramework>

或者

1   <appSettings>
2     <add key = "DatabaseInitializerForType EFDemo.DAL.SchoolContext,EFDemo" value = "EFDemo.DAL.SchoolInitializer,EFDemo" />
3   </appSettings>

它必須以預定義值DatabaseInitializerForType開頭,后跟一個空格,然后是上下文類的全名稱。

context節點,type指定上下文類的全名稱,后面是程序集的名稱。當你不想EF使用初始化,您可以給context元素設置一個屬性disableDatabaseInitialization="true"

作為在Web.config文件中設置初始化程序的替代方法是在Global.asax.cs文件中通過執行代碼來設置:

 1  protected void Application_Start()
 2  {
 3    AreaRegistration.RegisterAllAreas();
 4    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
 5    RouteConfig.RegisterRoutes(RouteTable.Routes);
 6    BundleConfig.RegisterBundles(BundleTable.Bundles);
 7 
 8    //指定數據庫初始化程序
 9    Database.SetInitializer(new SchoolInitializer()); 10  }

SetInitializer() 方法接受數據庫初始化程序類的實例,並將其設置為當前應用程序數據庫初始化程序。設置數據庫初始化程序時,不會立即調用。當第一次使用上下文(SchoolContext)時,它將被調用。

當首次訪問數據庫時,Entity Framework會將數據庫與模型進行比較,如果有差異,將刪除並重新創建數據庫。

如果在數據庫初始化時,不想使用延遲加載,可以使用Initialize()方法覆蓋。如果模型復雜且初始化需要很多時間,可以顯式調用數據庫初始化程序。這樣就可以在某個已知步驟執行初始化(並且可以向用戶顯示等待消息)。使用Initialize()方法,代碼如下所示:

1  Database.Initialize(false);//立刻初始化數據,不延遲加載

在上述代碼中,數據庫將在調用Initialize()方法后立即創建,而不是延遲加載。Initialize()方法接受一個布爾類型的參數,用於控制是否重新執行初始化。指定false,如果已經執行,則跳過初始化過程。指定true,將重新初始化,即使它已被初始化。

有時可能不希望執行數據庫初始化邏輯。在這種情況下,可以通過將null傳遞給SetInitializer()方法,則將跳過初始化。

1 Database.SetInitializer<SchoolContext>(null);

注意:如果將應用程序部署到生產環境,則必須刪除或禁用初始化代碼。

創建自定義數據庫初始化程序

在上述示例中,使用內置的數據庫初始化程序。還可以通過實現IDatabaseInitializer<>接口來創建自定義數據庫初始化程序。需要實現IDatabaseInitializer<>接口的InitializeDatabase()方法,並編寫自己的數據庫創建邏輯。以下代碼顯示了InitializeDatabase()方法的示例實現:

 1 public class SchoolInitializer : IDatabaseInitializer<SchoolContext>
 2     {
 3         #region 繼承 IDatabaseInitializer<SchoolContext>接口,實現InitializeDatabase()方法
 4         public void InitializeDatabase(SchoolContext context)
 5         {
 6             //判斷數據庫是否已經存在
 7             if (context.Database.Exists())
 8             {
 9                 //數據庫模式是否與模型兼容
10                 if (!context.Database.CompatibleWithModel(true))
11                 {
12                     context.Database.Delete();
13                 }
14             }
15             context.Database.Create();
16             //使用自定義初始值設置來執行自定義任務
17             context.Database.ExecuteSqlCommand("CREATE TABLE CS_DATA([Id] int identity(1,1) primary key, [Name] NVARCHAR(50) not null)");
18         }
19         #endregion
20     }

注意:代碼使用ExecuteSqlCommand()方法來創建不屬於模型的表。雖然我們在示例中不使用該表,但它說明了如何使用自定義初始化設置來執行自定義任務。

創建Student控制器和視圖

現在,將創建一個頁面來顯示數據,請求數據的過程將自動觸發數據庫的創建。先創建一個新的控制器。但是在這之前,需要重新生成整個項目,因為我們將使用MVC腳手架自動生成CRUD頁面。

  1. 右鍵單擊解決方案資源管理器中Controllers文件夾,選擇添加,然后單擊控制器
  2. 在彈出的對話框中,選擇包含視圖的MVC 5控制器(使用Entity Framework)

  3. 在“添加控制器”對話框中,進行以下選擇,然后單擊“ 添加”

    • 模特類:學生(Student(EFDemo.Models))(如果在下拉列表中沒有看到此選項,則重新生成項目,然后重試)
    • 數據上下文類:SchoolContext(EFDemo.DAL)
    • 控制器名稱:StudentController
    • 其他保留默認值。

 

當單擊添加時,將創建一個StudentController.cs文件和一組與控制器配合使用的視圖(.cshtml文件)。

4.Visual Studio打開Controllers \ StudentController.cs文件。您看到已經創建了一個實例化數據庫上下文對象的類變量:

1  private SchoolContext db = new SchoolContext();

Index操作方法通過數據庫上下文實例的屬性查詢出所有學生信息:

1   // GET: Student
2   public ActionResult Index()
3   {
4     return View(db.Students.ToList());
5   }

學生\ Index.cshtml視圖顯示此列表中的表:

 1 @model IEnumerable<EFDemo.Models.Student>
 2 
 3 @{
 4     ViewBag.Title = "Index";
 5 }
 6 
 7 <h2>Index</h2>
 8 
 9 <p>
10     @Html.ActionLink("Create New", "Create")
11 </p>
12 <table class="table">
13     <tr>
14         <th>
15             @Html.DisplayNameFor(model => model.LastName)
16         </th>
17         <th>
18             @Html.DisplayNameFor(model => model.FirstMidName)
19         </th>
20         <th>
21             @Html.DisplayNameFor(model => model.EnrollmentDate)
22         </th>
23         <th></th>
24     </tr>
25 
26 @foreach (var item in Model) {
27     <tr>
28         <td>
29             @Html.DisplayFor(modelItem => item.LastName)
30         </td>
31         <td>
32             @Html.DisplayFor(modelItem => item.FirstMidName)
33         </td>
34         <td>
35             @Html.DisplayFor(modelItem => item.EnrollmentDate)
36         </td>
37         <td>
38             @Html.ActionLink("Edit", "Edit", new { id=item.ID }) |
39             @Html.ActionLink("Details", "Details", new { id=item.ID }) |
40             @Html.ActionLink("Delete", "Delete", new { id=item.ID })
41         </td>
42     </tr>
43 }
44 
45 </table>
View Code

5.按CTRL + F5運行項目。(或Index.cshtml文件右擊在瀏覽器中查看或者直接按F5)

單擊“ 學生”選項卡以查看Seed()方法插入的測試數據

查看數據庫

當您運行學生頁面,應用程序嘗試訪問數據庫時,EF看到沒有數據庫,因此它創建了一個數據庫,然后運行Seed()方法添加測試數據。

因為正在使用DropCreateDatabaseIfModelChanges初始化程序,現在可以對Student進行更改,再次運行應用程序,將自動重新創建數據庫。例如,如果Student該類添加一個屬性EmailAddress,再次運行“學生”頁面,然后再次查看該表,將看到一個新列EmailAddress

1   public string EmailAddress { get; set; }

當重新運行時,可能會報這個錯:

解決辦法:先刪除原數據庫,勾選關閉現有連接,然后再運行程序。后面利用遷移就不需要手動刪除數據庫了。

然后查看數據庫,增加了新的列

約定

使用Entity Framework能夠創建一個完整的數據庫,發現我們只編寫了很少的代碼,因為Entity Framework有默認約定

  • 實體類名一般用作表名。
  • 實體屬性名稱用於列名。
  • 名稱ID或classnameID屬性被識別為主鍵屬性。
  • 還有外鍵屬性,例如,StudentID用於Student導航屬性

當然我們可以將屬性顯式地標記為外鍵屬性等。在本系列后面繼續學習。

 

參考:https://docs.microsoft.com/zh-cn/aspnet/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM