EF CodeOnly/CodeFirst设计模式实例演示

我们都知道EF有三种设计模式:DBFirst、ModelFirst、CodeFirst。前两种设置模式比较好理解、学习。具体学习可参考本人的另外两篇博文()。今天咱们主要来共同学习一下最不常用的设计模式:CodeFirst。

CodeFirst,中文大概意思,代码先行。那么这种设计模式相对于前两种设计模式而言有什么特别的地方呢?

DBFirst:就是先设计数据库,根据数据库生成实体类

ModleFirst:先设计表实体。通过映射生成数据库。(注意,这也是一种设计数据库的方法,而且相对于我们之前设计数据库的方式更直观。)

那么,CodeFirst这种设计模式数据库如何来呢?表实体又如何得到呢?好,带着这两个问题,我们开始今天设计模式的学习。

为了便于学习和更好的理解、掌握,我们通过一个具体的项目来展开学习。

先来说一下大致流程,我们新建一个测试项目,了解过原理之后进行代码实例测试,模拟一下用户添加、订单添加。


1.新建WinForm测试项目


这里只是为了说明CodeFirst设计模式,所以采用了比较简单的Winform项目形式。

新建项目CodeOnlyDemo

                                           EF CodeOnly/CodeFirst设计模式实例演示_第1张图片


创建好项目之后,我们还需要引入一些dll文件。如EntityFramwork.dll 、System.Data.Entity.dll、System.ComponentModel.DataAnnotations.dll。具体引入方法就不用在此累述了吧。

好吧,再累述一下上面几个dll文件的作用。

EntityFramwork.dll :EF框架的dll文件

System.Data.Entity.dll:实体文件

System.ComponentModel.DataAnnotations.dll:就本项目而言,是为了在下面的类属性上添加主键定义


2.添加实体类


在这里,我们添加两个类:Customer类、Order类、DemoContext类。Customer类是消费者类,Order是订单类,DemoContext类提供了一种类似与HttpContext的上下文机制,我们所有的更新操作都要通过该类进行。再进一步学习之前,我们需要了解一下消费者和订单两者之间是 一对多的关系。
两个类的具体定义如下。

(1)Customer类

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

namespace CodeOnlyDemo
{
   public class Customer
    {
       [Key]
       public Guid Id { get; set; }
       public string Name { get; set; }
       public string Password { get;set;}
       public ICollection<Order> Order { get; set; }
    }
}
这里只定义了该类的几个简要属性:Id、Name、Password、Order
这里有几点需要注意:
<1> 需要添加主键 具体通过在属性上方添加[Key]实现(后面需要根据这个类创建表,所以必须添加主键定义)
<2>由于Customer和Order之间是一对多的关系,所以需要在Customer类中定义一个Order集合形式的Order属性

(2)Order类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
namespace CodeOnlyDemo
{
    public class Order
    {
        [Key]
        public Guid Id { get; set; }

        public DateTime InsertTime { get; set; }

        public string Type { get; set; }

        public Customer customer { get; set; }
    }
}
注意:这里还需要在Order的属性中添加一个Customer类的属性。

(3)DemoContext类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Data.Entity;
using System.Configuration;
namespace CodeOnlyDemo
{
    public class DemoContext :DbContext
    {
        public DemoContext()
            : base("name=ConnCodeFirst")
        {

        }
        public DbSet<Order> order { get; set; }
        public DbSet<Customer> cunstomer { get; set; }
    }
}
关于该类的定义就没什么可说的了吧。算了,还是再说一下吧。
<1>在这里,我们继承的是DbContext类(还可以继承ObjectContext类,本人刚开始的时候使用的就是此类,不过在后面的配置文件读取过程中老是报错,还不知道如何解决,于是果断换成了DbContext)。
<2>该类的构造函数有点特别,调用的是基类的构造函数,我们看一下基类的构造函数定义。
        //
        // 摘要:
        //     Constructs a new context instance using the given string as the name or connection
        //     string for the database to which a connection will be made.  See the class
        //     remarks for how this is used to create a connection.
        //
        // 参数:
        //   nameOrConnectionString:
        //     Either the database name or a connection string.
        public DbContext(string nameOrConnectionString);
主要意思就是读取配置文件中链接字符串,创建链接对象。
<3>定义两个DbSet集,这个就没什么说的了。

3.添加配置文件App.Config


上面已经说了,上下文定义的时候需要从配置文件中读取连接字符串,新建配置文件,在里面添加数据库链接节点。
具体内容如下。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name="ConnCodeFirst" connectionString="server=.;uid=sa;pwd=123456;database=CodeFirstDemoDb" providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>
上面的内容如何得到就真的不用我再介绍了吧?
到目前为止,所有的工作我们已经做完了。那么到底我们做的对不对呢?下面进入具体的测试。

4.测试


4.1修改启动项

修改Program.cs文件如下
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace CodeOnlyDemo
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            DemoContext dbContext = new DemoContext();
            dbContext.Database.CreateIfNotExists();//不存在的情况下会创建对应的数据库
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new CustomerDemo());
        }
    }
}

4.2添加CustomerDemo窗体


4.2.1 窗体


EF CodeOnly/CodeFirst设计模式实例演示_第2张图片

4.2.2 .cs代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CodeOnlyDemo
{
    public partial class CustomerDemo : Form
    {
        public CustomerDemo()
        {
            InitializeComponent();
        }

        private void btn_add_Click(object sender, EventArgs e)
        {
            string username = this.txt_username.Text.Trim();
            string password = this.txt_password.Text;
            using (DemoContext context = new DemoContext())
            {
                context.cunstomer.Add(new Customer { Id = Guid.NewGuid(), Name = username, Password = password });
                if (context.SaveChanges() > 0)
                {
                    new OrderDemo(username).Show();
                }
            }
        }
    }
}

4.3添加OrderDemo窗体

4.3.1 窗体



4.3.2 .cs代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace CodeOnlyDemo
{
    public partial class OrderDemo : Form
    {
        public string username;
        public OrderDemo()
        {
            InitializeComponent();
        }
        public OrderDemo(string username)
            : this()
        {
            this.label2.Text = username;
            this.username = username;
        }
        private void btn_submit_Click(object sender, EventArgs e)
        {
            string name = this.txt_name.Text.Trim();
            using (DemoContext context = new DemoContext())
            {
                Customer customer1 = context.cunstomer.Where(c => c.Name == username).FirstOrDefault();
                context.order.Add(new Order { Id = Guid.NewGuid(), Type = name, InsertTime=DateTime.Now, customer = customer1 });
                if (context.SaveChanges() > 0)
                {
                    MessageBox.Show("添加成功");
                }
            }
        }
    }
}

4.4测试


4.4.1数据库建立

EF CodeOnly/CodeFirst设计模式实例演示_第3张图片

OK,当程序启动起来之后,会自动在数据库中帮助我们建立一个数据库。
再观察一下这个数据库中的表已经字段,是不是与我们在类中的定义完全一致呢?
细心的你一定发现了,并不是完全一致啊。确实是,表Customer中不存在Order集合,而Order表中存在一个外键。你可能会问是不是错了啊,其实是很正确。我们由此也可以看出,微软的这种设计模式是多么的智能。

4.4.2Customer添加


EF CodeOnly/CodeFirst设计模式实例演示_第4张图片

添加用户名、密码,点击提交。OK,到数据库中查看数据是否插入成功。


OK,插入成功。

4.4.3 提交订单


输入商品名称,点击提交,提示成功。
EF CodeOnly/CodeFirst设计模式实例演示_第5张图片

OK,到数据库中看个究竟。
EF CodeOnly/CodeFirst设计模式实例演示_第6张图片

OK,测试成功。
至此,所有工作完成。
PS:本人已经把项目中的所有代码贴出来了,实在不会的可以把代码复制出来。不过,动手才是王道。

你可能感兴趣的:(EF CodeOnly/CodeFirst设计模式实例演示)