zoukankan      html  css  js  c++  java
  • ado.net EF CodeOnly/CodeFirst设计模式实例演示

    我们都知道ado.net EF有三种设计模式:DBFirst、ModelFirst、CodeFirst。

    前两种设置模式比較好理解、学习。详细学习可參考本人的另外两篇博文()。

    今天咱们主要来共同学习一下最不经常使用的设计模式:CodeFirst。

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

    DBFirst:就是先设计数据库。依据数据库生成实体类

    ModleFirst:先设计表实体。

    通过映射生成数据库。

    (注意。这也是一种设计数据库的方法。并且相对于我们之前设计数据库的方式更直观。

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

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

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


    1.新建WinForm測试项目


    这里仅仅是为了说明CodeFirst设计模式。所以採用了比較简单的Winform项目形式。

    新建项目CodeOnlyDemo

                                               


    创建好项目之后。我们还须要引入一些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 窗口




    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数据库建立



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

    4.4.2Customer加入




    加入username、password,点击提交。OK。到数据库中查看数据是否插入成功。


    OK,插入成功。

    4.4.3 提交订单


    输入商品名称。点击提交,提示成功。



    OK。到数据库中看个到底。


    OK,測试成功。
    至此,全部工作完毕。

    PS:本人已经把项目中的全部代码贴出来了,实在不会的能够把代码复制出来。只是。动手才是王道。

  • 相关阅读:
    arm-linux-gcc编译时出现stray '357''273' '277' in program的解决方法
    C#中dynamic的正确用法
    C# 利用反射调用类下的方法
    C# 如何利用反射,将字符串转化为类名并调用类中方法
    将string转为同名类名,方法名。(c#反射)
    MethodInfo类的一般使用
    easyUi弹出window窗口传值与调用父页面的方法,子页面给父页面赋值
    [收集] 各式各样的 无限级分类 的数据库设计方案
    JavaScript随机生成信用卡卡号的方法
    C#中Invoke的用法
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/7258942.html
Copyright © 2011-2022 走看看