EF4.3 基於代碼的遷移演練


原文地址:http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx

原文名稱:EF 4.3 Code-Based Migrations Walkthrough

准備工作

在開始之前,我們需要一個項目,以及一個 Code First 的模型,對於這次演示,我們使用典型的博客 Blog 和回復 Post 模型。

1. 創建新的  MigrationsCodeDemo 控制台應用程序

2. 為項目添加最新版本的 EntityFramework NuGet 包。

找到包管理器控制台。

運行 Install-Package EntityFramework 命令。

成功之后的項目文件如下:

創建初始的模型和數據庫

1. 增加如下的 Model.cs 文件,代碼定義了一個單個的 Blog 類表示我們的模型對象,BlogContext 類就是 EF Code First 的上下文。

using System.Data.Entity;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.Infrastructure;

namespace MigrationsCodeDemo
{
public class BlogContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
}

public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
}
}

2. 現在我們已經有了一個模型,是時候進行一次數據訪問了。使用如下的代碼更新 Program.cs 文件。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MigrationsCodeDemo
{
class Program
{
static void Main(string[] args)
{
using (var db = new BlogContext())
{
db.Blogs.Add(new Blog { Name = "Another Blog " });
db.SaveChanges();

foreach (var blog in db.Blogs)
{
Console.WriteLine(blog.Name);
}
}
}
}
}

3. 運行程序,現在就可以在你本地的 SQLExpress 數據庫中看到數據庫了。

啟用遷移

1. 在 Blog 類中增加一個 Url 屬性。

    public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
}

2. 現在運行程序,會看到如下的異常。
未經處理的異常:  System.InvalidOperationException: The model backing the 'BlogContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

3. 正如異常建議,現在是開始使用 Code First 遷移的時候了,第一步是為我們的上下文啟用遷移支持。

   在包管理器的控制台中執行命令:Enable-Migrations

4. 這個命令在項目中增加名為 Migrations 文件夾,文件夾中包含兩個文件。

Configuration 類,這個類允許你配置你的上下文的遷移行為,在這個演示中,我們僅僅使用默認配置。

因為在這個項目中只有一個上下文,Enable-Migrations 自動填充應用的這個上下文。

201202171353373_InitialCreate.cs 中的 InitialCreate ,生成這個遷移是因為我們已經通過 Code First 創建了一個數據庫。這個遷移中的代碼表示我們已經創建的數據庫,

 

namespace MigrationsCodeDemo.Migrations
{
using System.Data.Entity.Migrations;

public partial class InitialCreate : DbMigration
{
public override void Up()
{
CreateTable(
"Blogs",
c => new
{
BlogId = c.Int(nullable: false, identity: true),
Name = c.String(),
})
.PrimaryKey(t => t.BlogId);

}

public override void Down()
{
DropTable("Blogs");
}
}
}

第一個遷移

你會使用到兩個命令

Add-Migration,將會基於你對模型的修改創建一個遷移的腳手架。

Update-Database,將沒有提交的修改提交到數據庫。

1. 我們首先為我們新增加的 Url 屬性創建一個遷移,Add-Migration 會幫我們完成這個工作,我們為這個遷移命名為:AddBlogUrl。

 執行:Add-Migration AddBlogUrl

項目中增加了一個文件 201202171413369_AddBlogUrl.cs

 


內容如下:

 

namespace MigrationsCodeDemo.Migrations
{
using System.Data.Entity.Migrations;

public partial class AddBlogUrl : DbMigration
{
public override void Up()
{
AddColumn("Blogs", "Url", c => c.String());
}

public override void Down()
{
DropColumn("Blogs", "Url");
}
}
}

3. 我們可以在這個遷移中編輯或者增加內容,但是現在看起來就很不錯,讓我們將這個遷移提交到數據庫中。

執行: Update-Database

4. 現在的數據庫中已經包含了 Url 列。

定制遷移

下面我們看看如何定制遷移。

1. 在代碼中增加一個回復的類 Post,同時在 Blog 中增加一個評分屬性。

using System.Data.Entity;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.Infrastructure;

namespace MigrationsCodeDemo
{
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public int Rating { get; set; }
public List<Post> Posts { get; set; }
}

public class Post
{
public int PostId { get; set; }
[MaxLength(200)]
public string Title { get; set; }
public string Content { get; set; }

public int BlogId { get; set; }
public Blog Blog { get; set; }
}
}

2. 使用 Add-Migration 命令創建一個遷移,命名為 AddPostClass。

3.  Code First Migrations 幫我們創建好了一個遷移,但是我們希望能增加如下的修改:

     首先,為 Posts.Title 增加一個唯一索引。

     增加一個非空的 Blogs.Rating 列,如果表中已經存在了數據,那么就將 CLR 默認的數據類型值賦予新增加的列 (Rating 是整數類型,應該就是 0), 但是,我們希望默認為 3, 這樣已經存在的博客會有一個不錯的評分。

namespace MigrationsCodeDemo.Migrations
{
using System.Data.Entity.Migrations;

public partial class AddPostClass : DbMigration
{
public override void Up()
{
CreateTable(
"Posts",
c => new
{
PostId = c.Int(nullable: false, identity: true),
Title = c.String(maxLength: 200),
Content = c.String(),
BlogId = c.Int(nullable: false),
})
.PrimaryKey(t => t.PostId)
.ForeignKey("Blogs", t => t.BlogId, cascadeDelete: true)
.Index(t => t.BlogId)
.Index(p => p.Title, unique: true);

AddColumn("Blogs", "Rating", c => c.Int(nullable: false, defaultValue: 3));
}

public override void Down()
{
DropIndex("Posts", new[] { "BlogId" });
DropForeignKey("Posts", "BlogId", "Blogs");
DropColumn("Blogs", "Rating");
DropTable("Posts");
}
}
}

4. 運行 Update-Database 提交到數據庫,這次可以使用一個參數 -Verbose,以便可以看到生成的 SQL 腳本。

數據操作/定制 SQL

我們已經完成的遷移並沒有修改或者移動任何數據,我們可以在遷移中的任何地點運行任意腳本。

1. 在模型上增加一個摘要 PostAbstrack 屬性,然后,希望使用已經發布的內容來填充這個摘要屬性。

public class Post
{
public int PostId { get; set; }
[MaxLength(200)]
public string Title { get; set; }
public string Content { get; set; }
public string Abstract { get; set; }

public int BlogId { get; set; }
public Blog Blog { get; set; }
}

2. 創建一個遷移。

3. 修改生成的遷移文件,

namespace MigrationsCodeDemo.Migrations
{
using System.Data.Entity.Migrations;

public partial class AddPostAbstract : DbMigration
{
public override void Up()
{
AddColumn("Posts", "Abstract", c => c.String());

Sql("UPDATE Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL");

}

public override void Down()
{
DropColumn("Posts", "Abstract");
}
}
}

4. 更新數據庫之后,就會得到最新的數據了。使用 Verbose 參數可以看到提交的腳本。


遷移到特定版本(包含降級)

你可以升級或者降級到特定的版本。

假設我們希望數據庫遷移到執行 AddBlogUrl 遷移之后的狀態,通過 -TargetMigration 參數來降級。

如果你希望回到最初的空數據庫,可以使用參數 TargetMigration:$InitialDatabase.

獲取遷移的腳本

在運行 Update-Database 的時候,使用參數 -Script 。

-SourceMigration:$InitialDatabase 用來指定起始的版本, -TargetMigration:"AddPostAbstract" 用來指定目標版本。

我們希望取得從初始的數據庫,直到遷移到 AddPostAbstract 版本使用的腳本。

執行之后,得到一個腳本文件。

CREATE TABLE [Blogs] (
[BlogId] [int] NOT NULL IDENTITY,
[Name] [nvarchar](max),
CONSTRAINT [PK_Blogs] PRIMARY KEY ([BlogId])
)
CREATE TABLE [__MigrationHistory] (
[MigrationId] [nvarchar](255) NOT NULL,
[CreatedOn] [datetime] NOT NULL,
[Model] [varbinary](max) NOT NULL,
[ProductVersion] [nvarchar](32) NOT NULL,
CONSTRAINT [PK___MigrationHistory] PRIMARY KEY ([MigrationId])
)
BEGIN TRY
EXEC sp_MS_marksystemobject '__MigrationHistory'
END TRY
BEGIN CATCH
END CATCH
INSERT INTO [__MigrationHistory] ([MigrationId], [CreatedOn], [Model], [ProductVersion]) VALUES ('201202171353373_InitialCreate', '2012-02-17T14:51:25.032Z', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E074A10880601324D8904010ECC188CDE692EC1D69472329AB2A81CA6556655D661640CCED9DBCF7DE7BEFBDF7DE7BEFBDF7BA3B9D4E27F7DFFF3F5C6664016CF6CE4ADAC99E2180AAC81F3F7E7C1F3F22FEC7BFF71F7CFC7BBC5B94E9655E3745B5FCECA3DDF1CE4769BE9C56B36279F1D947EBF67CFBE0A3DFE3E8374E1E9FCE16EFD29F34EDF6D08EDE5C369F7D346FDBD5A3BB779BE93C5F64CD78514CEBAAA9CEDBF1B45ADCCD66D5DDBD9D9D83BBBB3B777302F111C14AD3C7AFD6CBB658E4FC07FD79522DA7F9AA5D67E517D52C2F1BFD9CBE79CD50D317D9226F56D934FFECA32F8A8B3A6B098BE684DA3ECD17D547E971596484C9EBBC3C7F4FB4761E02AD8F6C87D4E529A1D65EBFB95EE5DCED671F3D29AB0BBF05B5F9BDF2EBE003FAE8655DADF2BABD7E959F7BEF9DCD3E4AEF86EFDEEDBE6C5FEDBC07143EFBE86CD9DEDBFB287DB12ECB6C52D207E759D9E41FA5AB4F1FBD6EAB3AFF3C5FE644907CF6326BDBBCA6C9399BE53C0425C5A3D5A7B7A3C6C3BB3B7BA0C6DD6CB9AC5AA6710FF90EAAF8D720FABAAD89693E4A9F15EFF2D9F37C79D1CE2DB25F64EFCC27F4EB47E957CB82788C5E6AEB75EE0F4EFEDEDCE95775F9B3DCE7E3BB8E09FAAC41DCDA660551DD9B2F7C96BF6B3B6C22ED5FE7ADD7B2F92875C08567C7CC61510C6C5F4E24EE8A4C18D9B93B203C8FBFC8562B228E274CFA49FA5A24E964FBF5FB4BCB4260DC9D3611A1B1D8DA9E8843B38BBCF32D754D983E2BEAA67D9AB5D924C3749DCC16BD66B7A0ACE9C9277057341DBD4D6BFC2E6FF4D5C9B82FEF0C45DF7D46035A9080F1D8746484474C4DE88BAFA75999D503427E5295EBC57293C2D80445E4CF87219FDC1E020B930F803FE8BFFFF86E67FC5D227B22A32D3B6AAF3B659BB8BDDBC4F66EB9BEC3DD8F95D36EB61F3DD693261FA54498CB6206B67B7DDDB4F9628C06E3D7BFA83C290B1AAF6BF045B62CCEF3A67D53BDCD610B4932BEBE09B24AB76966E5FF9BED500112DC68717A66EAF6F6637999D5D379566F2DB277773EC026BC079CF7D3F37DA575B3B61F54F6C2759F7D349B90FFF2461054F3F035ED405F021EDFF5FDACC74FF3A6B87020E0752DF329749F036ADA9C2DCF2B43621A918F9169D299812FF2369B11618EEBB638CFA62D7D3DCD9B86CDF34F66E59A9A9C2E26F9EC6CF9E5BA5DADDBE3A6C91793F2DA1FEFE3BB9BFB676317E2FCF8CB156BEF6F620884664143C8BF5C3E5917E5CCE2FDACCFCA4320C0232A1F8415B92704EEE2DA427A512D6F0948C9F7345FE54B48D79B7CB12A0958F3E5F27576990FE376330D438A3D7E5A646402173E05E513C5E475463D7B5D5007FE1BAE3FFA93D8959CFCA3FF270000FFFF2B65B379590C0000, '4.3.0')
ALTER TABLE [Blogs] ADD [Url] [nvarchar](max)
INSERT INTO [__MigrationHistory] ([MigrationId], [CreatedOn], [Model], [ProductVersion]) VALUES ('201202171413369_AddBlogUrl', '2012-02-17T14:51:25.079Z', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E074A10880601324D8904010ECC188CDE692EC1D69472329AB2A81CA6556655D661640CCED9DBCF7DE7BEFBDF7DE7BEFBDF7BA3B9D4E27F7DFFF3F5C6664016CF6CE4ADAC99E2180AAC81F3F7E7C1F3F22FEC7BFF71F7CFC7BBC5B94E9655E3745B5FCECA3DDF1CE4769BE9C56B36279F1D947EBF67CFBE0A3DFE3E8374E1E9FCE16EFD29F34EDF6D08EDE5C369F7D346FDBD5A3BB779BE93C5F64CD78514CEBAAA9CEDBF1B45ADCCD66D5DDBD9D9D83BBBB3B777302F111C14AD3C7AFD6CBB658E4FC07FD79522DA7F9AA5D67E517D52C2F1BFD9CBE79CD50D317D9226F56D934FFECA32F8A8B3A6B098BE684DA3ECD17D547E971596484C9EBBC3C7F4FB4761E02AD8F6C87D4E529A1D65EBFB95EE5DCED671F3D29AB0BBF05B5F9BDF2EBE003FAE8655DADF2BABD7E959F7BEF9DCD3E4AEF86EFDEEDBE6C5FEDBC07143EFBE86CD9DEDBFB287DB12ECB6C52D207E759D9E41FA5AB4F1FBD6EAB3AFF3C5FE644907CF6326BDBBCA6C9399BE53C0425C5A3D5A7B7A3C6C3BB3B7BA0C6DD6CB9AC5AA6710FF90EAAF8D720FABAAD89693E4A9F15EFF2D9F37C79D1CE2DB25F64EFCC27F4EB47E957CB82788C5E6AEB75EE0F4EFEDEDCE95775F9B3DCE7E3BB8E09FAAC41DCDA660551DD9B2F7C96BF6B3B6C22ED5FE7ADD7B2F92875C08567C7CC61510C6C5F4E24EE8A4C18D9B93B203C8FBFC8562B228E274CFA49FA5A24E964FBF5FB4BCB4260DC9D3611A1B1D8DA9E8843B38BBCF32D754D983E2BEAA67D9AB5D924C3749DCC16BD66B7A0ACE9C9277057341DBD4D6BFC2E6FF4D5C9B82FEF0C45DF7D46035A9080F1D8746484474C4DE88BAFA75999D503427E5295EBC57293C2D80445E4CF87219FDC1E020B930F803FE8BFFFF86E67FC5D227B22A32D3B6AAF3B659BB8BDDBC4F66EB9BEC3DD8F95D36EB61F3DD693261FA54498CB6206B67B7DDDB4F9628C06E3D7BFA83C290B1AAF6BF045B62CCEF3A67D53BDCD610B4932BEBE09B24AB76966E5FF9BED500112DC68717A66EAF6F6637999D5D379566F2DB277773EC026BC079CF7D3F37DA575B3B61F54F6C2759F7D349B90FFF2461054F3F035ED405F021EDFF5FDACC74FF3A6B87020E0752DF329749F036ADA9C2DCF2B43621A918F9169D299812FF2369B11618EEBB638CFA62D7D3DCD9B86CDF34F66E59A9A9C2E26F9EC6CF9E5BA5DADDBE3A6C91793F2DA1FEFE3BB9BFB676317E2FCF8CB156BEF6F620884664143C8BF5C3E5917E5CCE2FDACCFCA4320C0232A1F8415B92704EEE2DA427A512D6F0948C9F7345FE54B48D79B7CB12A0958F3E5F27576990FE376330D438A3D7E5A646402173E05E513C5E475463D7B5D5007FE1BAE3FFA93D8959CFCA3FF270000FFFF2B65B379590C0000, '4.3.0')
CREATE TABLE [Posts] (
[PostId] [int] NOT NULL IDENTITY,
[Title] [nvarchar](200),
[Content] [nvarchar](max),
[BlogId] [int] NOT NULL,
CONSTRAINT [PK_Posts] PRIMARY KEY ([PostId])
)
CREATE INDEX [IX_BlogId] ON [Posts]([BlogId])
CREATE UNIQUE INDEX [IX_Title] ON [Posts]([Title])
ALTER TABLE [Blogs] ADD [Rating] [int] NOT NULL DEFAULT 3
ALTER TABLE [Posts] ADD CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([BlogId]) ON DELETE CASCADE
INSERT INTO [__MigrationHistory] ([MigrationId], [CreatedOn], [Model], [ProductVersion]) VALUES ('201202171424494_AddPostClass', '2012-02-17T14:51:25.092Z', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E074A10880601324D8904010ECC188CDE692EC1D69472329AB2A81CA6556655D661640CCED9DBCF7DE7BEFBDF7DE7BEFBDF7BA3B9D4E27F7DFFF3F5C6664016CF6CE4ADAC99E2180AAC81F3F7E7C1F3F22FEC7BFF71F7CFC7BBC5B94E9655E3745B5FCECA3DDF1CE4769BE9C56B36279F1D947EBF67CFBE0A3DFE3E8374E1E9FCE16EFD29F34EDF6D08EDE5C369F7D346FDBD5A3BB779BE93C5F64CD78514CEBAAA9CEDBF1B45ADCCD66D5DDBD9D9D83BBBB3B777302F111C14AD3C7AFD6CBB658E4FC07FD79522DA7F9AA5D67E517D52C2F1BFD9CBE79CD50D317D9226F56D934FFECA32F8A8B3A6B098BE684DA3ECD17D547E971596484C9EBBC3C7F4FB4761E02AD8F6C87D4E529A1D65EBFB95EE5DCED671F3D29AB0BBF05B5F9BDF2EBE003FAE8655DADF2BABD7E959F7BEF9DCD3E4AEF86EFDEEDBE6C5FEDBC07143EFBE86CD9DEDBFB287DB12ECB6C52D207E759D9E41FA5AB4F1FBD6EAB3AFF3C5FE644907CF6326BDBBCA6C9399BE53C0425C5A3D5A7B7A3C6C3BB3B7BA0C6DD6CB9AC5AA6710FF90EAAF8D720FABAAD89693E4A9F15EFF2D9F37C79D1CE2DB25F64EFCC27F4EB47E957CB82788C5E6AEB75EE0F4EFEDEDCE95775F943EFF31591031D6D9E930E8C17D96571C174EC407B59356DF351FA2A2F8593E7C54AB8778C6F7E7F66B8F4595D2D5E55A536E70F7FFF37597D91B78446D5FDE675B5AEA71D141EDF75BCBC91C301E6EB7038DEFB3A1C6EDEFBFF0087BF29DAF27D599C7AFA40762385D8D210DFB3DF0F67F3DBA99EDBB2B9F0F1FB73B9E1E53E971BFEBF0D971F374D352DB86B8FEDA4DB7000A7CB593A88834C80C19AE8BD2EDB62551653EAF2B38FBED5A3460C98155B074C461F02DB0DF122605F2E9FE665DEE6E9F114E320C6C89A6936EBCF01D160167E42529AD71093AC246E6ADA3A2B966D5FA48BE5B45865E510CA9D17DEC3CE01290BBEFBCDD37C952F21C44374FFB07E2DF80E916EA2C9E3BB1ED3F43526A492DEC86B0F0196D4775DED29ED5FE7ADD79214BE63D4800B7A1C14BEACD6A2F7B2F063E7656F0021049537EFFB9E3076E9B8492E2C9216BFDE346C9204EF75A54D97A1C38144E4DDCE86FDEEF15D7117F583C77707FCCAC75F64AB152954CFCFD44FD2D7E2649E6CBF7E7F47722130EE4E9B883F69B1B53D9169CB2EF2CEB750FDB3FC595137EDD3ACCD2619F4EDC96CD16B760BDE333DF92CD89F23C354A6357E9737FA9EF638C6268E7ACF68400B08359BEDCE14F75F4BE1DE6765560F18A193AA5C2F969B657D188AB8A63E0CF9E4F610D8CFF401F007B77FDFF88C3E08F3591FCAE3BB1D2AF6B45A6FAE7A26209CF85BB18508EF07B245DF7F642837B145FCB521721AA7D12767DC01DD0445FD391F887E747B18D63BF3A1D80F6F0FE7FD18FD6795417A4AB5DBC4F66E956B47893E568516685A1E793782EF693869F2514AE4B92C66D06EAFAF9B365F8CD160FCFA17952765C1A4350DBEC896C579DEB46FAAB7F992FDED83AF9F04B04141D3CCCAFF3767020A90E0C688E8266F7D4304BFBCCCEAE93CABB716D9BB3BEF1B3A7851F907C109236D1EF3C621FD7F24C8FD5999BC20383554EF87A2EF37019DD8F3832633C2C05F6B32BF4E2C27FEEE0F33E40A1DDEAF113B7EAD986DC027BBAD16C248DE2B4EFBC0BE2CC80E35BFE1D8ACEF4677E7AA1FA10D066862A03EFB6836A164F31BE1DE78D8D2052BF3DE032B1FC7C04683A99FA5A8CE1FB3F3D36F0AE47AB1DFCF4EECD677278847D64BBB6C40BCD914170E04161196F934E00EDBE66C795E1926ED60649A7434D717799BCD88758EEBB638CFA62D7D3DCD9B864DD34F66E59A9A9C2E26F9EC6CF9E5BA5DAD5B1A72BE9894D73E31C0EC9BFAE70035C4F9F1972B76ADBF8921109A050D21FF72F9645D94338BF7B388DE1D000129527B85B96C61B72EAE2DA417D5F29680947C4F8DF0BFC9172B4A0BE6CD97CBD7D9653E8CDBCD340C29F6F86991517CB2F029289F2826AF33EAD9EB823AF0DF70FDD19FC4AEB46675F4FF040000FFFFFA5ABE06281B0000, '4.3.0')
ALTER TABLE [Posts] ADD [Abstract] [nvarchar](max)
UPDATE Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL
INSERT INTO [__MigrationHistory] ([MigrationId], [CreatedOn], [Model], [ProductVersion]) VALUES ('201202171437449_AddPostAbstract', '2012-02-17T14:51:25.111Z', 0x1F8B0800000000000400ECBD07601C499625262F6DCA7B7F4AF54AD7E074A10880601324D8904010ECC188CDE692EC1D69472329AB2A81CA6556655D661640CCED9DBCF7DE7BEFBDF7DE7BEFBDF7BA3B9D4E27F7DFFF3F5C6664016CF6CE4ADAC99E2180AAC81F3F7E7C1F3F22FEC7BFF71F7CFC7BBC5B94E9655E3745B5FCECA3DDF1CE4769BE9C56B36279F1D947EBF67CFBE0A3DFE3E8374E1E9FCE16EFD29F34EDF6D08EDE5C369F7D346FDBD5A3BB779BE93C5F64CD78514CEBAAA9CEDBF1B45ADCCD66D5DDBD9D9D83BBBB3B777302F111C14AD3C7AFD6CBB658E4FC07FD79522DA7F9AA5D67E517D52C2F1BFD9CBE79CD50D317D9226F56D934FFECA32F8A8B3A6B098BE684DA3ECD17D547E971596484C9EBBC3C7F4FB4761E02AD8F6C87D4E529A1D65EBFB95EE5DCED671F3D29AB0BBF05B5F9BDF2EBE003FAE8655DADF2BABD7E959F7BEF9DCD3E4AEF86EFDEEDBE6C5FEDBC07143EFBE86CD9DEDBFB287DB12ECB6C52D207E759D9E41FA5AB4F1FBD6EAB3AFF3C5FE644907CF6326BDBBCA6C9399BE53C0425C5A3D5A7B7A3C6C3BB3B7BA0C6DD6CB9AC5AA6710FF90EAAF8D720FABAAD89693E4A9F15EFF2D9F37C79D1CE2DB25F64EFCC27F4EB47E957CB82788C5E6AEB75EE0F4EFEDEDCE95775F943EFF31591031D6D9E930E8C17D96571C174EC407B59356DF351FA2A2F8593E7C54AB8778C6F7E7F66B8F4595D2D5E55A536E70F7FFF37597D91B78446D5FDE675B5AEA71D141EDF75BCBC91C301E6EB7038DEFB3A1C6EDEFBFF0087BF29DAF27D599C7AFA40762385D8D210DFB3DF0F67F3E349D3D6D9F487DFF1ED74DE6DE54B04E8FDC5CB08515FBC8CE0DD46BC8E9BA69A16DCB5C7EFD26D3880D3E52C1DC44126C0604DF45E976DB12A8B2975F9D947DFEA512306CCEA0B074C461F02DB0DF122605F2E9FE665DEE6E9F114E3208ECC9A6936EBCF01D160167E42EA21AF219F59496C0C7E2A966D5F9714CB69B1CACA21943B2FBC87810552167CF79BA7F92A5F427B0CD1FDC3FAB5E03B44BA89268FEF7A4CD357D55007F4465E7B08B08A78D755DBD2FE75DE7A2DC9D238460DB8A0C741E1CB6AA67A2F0B3F765EF60610425079F3BEEF0963978E9BE4C22269F1EB4DC32649F05E57DA74193A1C4844DEED6CD8EF1EDF153F553F787C77C0A17DFC45B65A9142F51C5CFD247D2DDEEDC9F6EBF7F7601702E3EEB48938B2165BDB13D9D4EC22EF7C0B9B33CB9F1575D33ECDDA6C9241DF9ECC16BD66B7E03DD393CF82FD39324C655AE37779A3EFE28F636CE2A8F78C06B48050B3BFD099E2FE6B29E28AACCCEA0123745295EBC572B3AC0F43119FD887219FDC1E023BB83E00FEE0F6EF1B67D507613EEB43797CB743C59E56EBCD55CF0484137F2BB610E1FD40B6E83BAE0CE526B688BF36444EE3ADFAE48C7BBE9BA0A823E903D18F6E0FC3BA853E14FBE1EDE13837CF07E43EBD3DA4F713999F5556EBA9E76E13DBBB55D31D75FC585563A0B379E4DD24444F574A938F5222CF6531839E7C7DDDB4F9628C06E3D7BFA83C290B9E24D3E08B6C599CE74DFBA67A9B2F396438F8FA790C1BD734CDACFC7F7332A300096E0CEA6EF2FB3724219697593D9D67F5D6227B77E77D83102FB1F04170C264018F79E390FE3F12A7FFAC4C5E105F1BAAF7A3E9F79B804EF8FC4193D90D893F0858441ABE16677C9D1053DCF01F662418FAE15F23A4FD5AA1E480AB785B958691BC57F8F8817D59901D6A7EC32163DFBB3FEACC553F701C8C1BC5DA7DF6D16C42C9F737C2BDF168AA0B56E6BD07563E8E818DC6783F4BC1A63F66173EDC145FF642D29F9D90B2EF9B108FAC9776198578B3292E1C082CAA2CF369C01DB6CDD9F2BC324CDAC1C834E968AE2FF2369B912F735CB7C539A943FA7A9A370DDBB99FCCCA3535395D4CF2D9D9F2CB75BB5AB734E47C3129AF7D6280D937F5CF717388F3E32F57ECF17F134320340B1A42FEE5F2C9BA286716EF6711BD3B000252A4C60F73D9C2085E5C5B482FAAE52D0129F99E1AE17F932F5694ADCC9B2F97AFB3CB7C18B79B691852ECF1D322A3B069E153503E514C5E67D4B3D70575E0BFE1FAA33F895D690DEFE8FF090000FFFF18018B3A381C0000, '4.3.0')





免責聲明!

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



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