• 初识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已经讨论讲解完毕,个人能力有限,可能文中会有错漏的地方,欢迎各位朋友指正以及提出建议。

  • 相关阅读:
    [LeetCode] Search for a Range
    [C++] extern关键字的作用
    [LeetCode] Sentence Similarity
    [LeetCode] Flood Fill
    [LeetCode] Can Place Flowers
    [LeetCode] Intersection of Two Linked Lists
    [LeetCode] My Calendar II
    [LeetCode] My Calendar I
    [LeetCode] Self Dividing Numbers
    [LeetCode] Range Sum Query
  • 原文地址:https://www.cnblogs.com/xiaodiejinghong/p/2981232.html
Copyright © 2020-2023  润新知