初識Entity Framework CodeFirst(3)


前兩回合,我們討論學習了如何采用Entity Framework在沒有數據庫的情況下自己寫一些實體類,然后通過CodeFirst反向生成對應的數據庫。通過CodeFirst,我們擺脫了edmx文件,沒有了繁瑣的Xml關系映射,使代碼變得無比的清晰,修改起來也變得更加容易。

在前兩篇文章中,我們的數據庫都是通過反向生成的,也就是說,屬於一個New Database(新數據庫),那么,對於一個Exist Database(已存在的數據庫),我們又應該怎么辦呢?本節文章,我們將對 Code First to an Existing Database 做出討論學習。

本回合我們將討論:

1、介紹使用“Entity Framework Power Tools“ 工具

2、EF CodeFirst to Existing Database 的快速入門

3、了解”Entity Framework Power Tools“ 工具為我們做了哪些事

案例代碼可以點擊這里下載


1、Entity Framework Power Tools 工具

在看完本節的導讀時,也許你已經有了自己的一點想法:“按照我的數據庫結構,自己手寫出一些對應的實體Model,然后再寫一個繼承自DbContext的上下文……”。沒錯,恭喜你,你的想法理論上確實是可行的,至少在表不太多的情況下是可行的。但是,如果這個數據庫的表有很多呢,數目已經達到了上百個或者更多呢?明顯的,我們如果想自己手寫實體和上下文,那無疑是一件巨大的工程。

既要懂得原理,也要懂得效率;我們要做某一件事,必須先要懂得它的原理,為什么要這么做,知其然知其所以然,所謂“原理先行”嘛。懂了了原理之后,我們需要提高效率,這在當今這個效率就是金錢的時代中尤為重要。

不扯開話題,下面我為大家介紹一款工具,它的名字就是:“Entity Framework Power Tools”,它的可以實現,對數據庫中已存在的表自動的生成相應的實體和上下文。這款工具的下載地址各位讀者可以點擊這里獲得最新版的下載。

各位讀者下載下來之后,雙擊打開安裝,然后再重啟Visual Studio實例,就可以使用啦。

 

2、快速入門(快速案例)

我們新建一個解決方案                          

再看看我們的數據庫,這里我采用上回合反向生成的數據庫(由於VS自帶的數據庫管理器用起來速度太慢,我額外裝了一個“SQL Server Management Studio”,數據庫實例還是采用原先的輕量級數據庫LocalDB,區別的僅僅是管理工具不同,數據庫實例還是一樣,各位讀者不必感覺疑惑)

右鍵點擊解決方案,我們發現了一些新東西

這就是我們剛才安裝的EF工具,順着點擊進去,我們會彈出一個SQL Server的連接窗口,填寫好相應的連接信息,點擊確定

稍等一會兒,系統會自動的連接數據庫,然后遍歷所有的表,並根據表結構生成一些代碼。

我們可以看到,解決方案中多了一個“Model”文件夾,里面包含有上下文、一些Model、“Mapping”文件夾以及其下的Map文件(映射文件)

我們先不解釋里面的東西,先在Program中寫調用代碼,解釋留到第三節再解析。

我們在Program中寫如下調用代碼:

class Program
    {
        static void Main(string[] args)
        {
            using (var db = new CodeFirst_2013_3_23BlogContextContext())
            {
                Console.Write("Enter a name for a new blog:");
                var name = Console.ReadLine();
                var blog = new Blog { BlogName = name };
                db.Blogs.Add(blog);
                db.SaveChanges();

                var result = from b in db.Blogs
                             select b;
                foreach (var item in result)
                {
                    Console.WriteLine(item.BlogName);
                }
            }
            Console.ReadKey();
        }
    }

F5,調試:

可以正常執行(上面那個小蝶驚鴻是上回合CodeFirst操作中遺留下來的數據)

 

3、EF工具幫我們生成了什么

上一節我們是一個快速入門,這一節我們看看EF Tool幫我們生成了些什么代碼。

先看一下App.config

App.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="CodeFirst_2013_3_23BlogContextContext" connectionString="Data Source=(localdb)\mydb;Initial Catalog=CodeFirst_2013_3_23.BlogContext;Integrated Security=True;MultipleActiveResultSets=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
  </startup>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>
</configuration>

系統幫我們自動的填寫配置信息,值得注意的是“connectionStrings”節點,這里配置了EF的連接字串,在初始化上下文的對象時,上下文的構造函數會默認的傳入這里的連接字串。

<connectionStrings>
    <add name="CodeFirst_2013_3_23BlogContextContext" connectionString="Data Source=(localdb)\mydb;Initial Catalog=CodeFirst_2013_3_23.BlogContext;Integrated Security=True;MultipleActiveResultSets=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>

進入“Model”文件夾

這里生成了一些實體類文件:

Post實體:

Post
    public partial class Post
    {
        public int PostID { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public int BlogID { get; set; }
        public virtual Blog Blog { get; set; }
    }

Blog實體:

Blog
public partial class Blog
    {
        public Blog()
        {
            this.Posts = new List<Post>();
        }

        public int BlogID { get; set; }
        public string BlogName { get; set; }
        public string Url { get; set; }
        public virtual ICollection<Post> Posts { get; set; }
    }

Type實體:

Type
public partial class Type
    {
        public int TypeID { get; set; }
        public string TypeName { get; set; }
    }

User實體:

User
public partial class User
    {
        public string UserName { get; set; }
        public string Display_Name { get; set; }
    }

還有上下文類CodeFirst_2013_3_23BlogContextContext:

CodeFirst_2013_3_23BlogContextContext
public partial class CodeFirst_2013_3_23BlogContextContext : DbContext
    {
        static CodeFirst_2013_3_23BlogContextContext()
        {
            Database.SetInitializer<CodeFirst_2013_3_23BlogContextContext>(null);
        }

        public CodeFirst_2013_3_23BlogContextContext()
            : base("Name=CodeFirst_2013_3_23BlogContextContext")
        {
        }

        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
        public DbSet<Type> Types { get; set; }
        public DbSet<User> Users { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Configurations.Add(new BlogMap());
            modelBuilder.Configurations.Add(new PostMap());
            modelBuilder.Configurations.Add(new TypeMap());
            modelBuilder.Configurations.Add(new UserMap());
        }
    }

該上下文構造方法調用了父類DbContext的構造方法,傳入配置文件中的數據庫連接字串來連接需要的數據庫。

(反編譯DbContext得知其構造方法實際上是重載的方法,我們可以傳入多種的參數形式,這里我們不做過多的介紹)

最后,我們進入“Mapping”文件夾

里面包含的都是實體與數據庫,屬性與字段映射的關系文件,作用跟使用edmx文件時,那繁瑣的XML映射作用是一樣的,不過,采用CodeFirst方式生成的關系映射,代碼都是C#語言的,並且看起來相當清晰,以后重構起來也比edmx的XML方便得多。


至此,本回合的CodeFirst to Existing Database已經討論講解完畢,個人能力有限,可能文中會有錯漏的地方,歡迎各位朋友指正以及提出建議。

 

 


免責聲明!

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



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