EF学习和使用(三)Code First

Code First模式我们称之为“代码优先”模式,从某种角度来看,其实“Code First”和“Model First”区别并不是太明显,只是它不借助于实体数据模型设计器,而是直接通过编码方式设计实体模型(这也是为什么最开始“Code First”被叫做“Code Only”的原因)。但是对于EF它的处理过程有所差别,例如我们使用Code First就不再需要EDM文件,所有的映射通过“数据注释”和“fluent API”进行映射和配置。

另外需要注意的是“Code First”并不表示一定就要手动编写实体类,事实上如果有数据库的话可以取巧,通过现有数据库直接生成实体类。


Code First如何使用


首先

创建一个控制台应用程序,接下来添加两个类“Order”和“OrderDetail”,需要注意的是这两个类有两个导航属性“Order.OrderDetails”和“OrderDetail.Order”:

using System;
using System.Collections.Generic;
namespace CodeFirst
{
    public class Order
    {
        public int Id { get; set; }
        public string Customer { get; set; }
        public System.DateTime OrderDate { get; set; }

        public virtual List OrderDetails { get; set; }
    }
}

using System;
using System.Collections.Generic;
namespace CodeFirst
{
    public partial class OrderDetail
    {
        public int Id { get; set; }
        public string Product { get; set; }
        public string UnitPrice { get; set; }
        public int OrderId { get; set; }

        public virtual Order Order { get; set; }
    }
}

其次

有了这两个类之后还需要定义一个数据库上下文,来进行数据操作,这个类必须继承于”System.Data.Entity.DbContext”类。因此接下来我们需要引入EntityFramework包,可通过NuGet进行在线安装,

数据库上下文操作类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
namespace CodeFirst
{
    public class OrderContext : DbContext
    {
        public DbSet Orders { get; set; }
        public DbSet OrderDetails { get; set; }
    }

}

测试

然后我们进行测试,在这个类中我们首先创建了一个Order实例,接着编码查询:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CodeFirst
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var ctx = new OrderContext())
            {
var o = new Order();
                o.OrderDate = DateTime.Now;
                ctx.Orders.Add(o);
                ctx.SaveChanges();
var query = from order in ctx.Orders
                            select order;
                foreach (var q in query)
                {
                    Console.WriteLine("OrderId:{0},OrderDate:{1}", q.Id, q.OrderDate);
                }
Console.Read();
            }
        }
    }
}


查询结果如图:

EF学习和使用(三)Code First_第1张图片



哎等等好像哪里不对!

咱们明明没有进行任何数据库的配置,没有说明往哪个数据库添加,也没有设置连接字符串。但是增加了一条数据,通过查询发现确实保存上了,那么我们的数据到底在哪呢?事实上如果用户不进行数据库配置EF默认会使用“.\SQLEXPRESS”数据库实例,如果你没有安装“.\SQLEXPRESS”则默认使用LocalDb,关于LocalDb的具体细节请看:SQL Server 2012 Express LocalDB,一般会存放在目录:“C:\Users\用户名”,可以看到创建了一个名为“CodeFirst.OrderContext”的数据库:

EF学习和使用(三)Code First_第2张图片




但是正常情况下我们是需要自己控制建立数据库的,例如我想让他保存在某台服务器上,并且数据库的名字是“CodeFirstDb”,此时我们就需要在配置文件App.Config中配置一个数据库连接串,然后在我们的数据库上下文中指定这个连接名称。


在配置文件中添加:

  <connectionStrings>
    <add name="CodeFirstDb" connectionString="Data Source=.;Database=CodeFirstDb;UID=sa;PWD=123456;" providerName="System.Data.SqlClient">add>
  connectionStrings>


修改OrderContext类:

构造函数多了一个连接名参数:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
namespace CodeFirst
{

    public class OrderContext : DbContext
    {
        public OrderContext(string connectionName)
            : base(connectionName) { }

        public DbSet Orders { get; set; }
        public DbSet OrderDetails { get; set; }
    }
}

客户端使用:

传入配置的数据库连接字符串名称:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CodeFirst
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var ctx = new OrderContext("CodeFirstDb"))
            {
var o = new Order();
                o.OrderDate = DateTime.Now;
                ctx.Orders.Add(o);
                ctx.SaveChanges();
var query = from order in ctx.Orders
                            select order;
                foreach (var q in query)
                {
                    Console.WriteLine("OrderId:{0},OrderDate:{1}", q.Id, q.OrderDate);
                }
Console.Read();
            }
        }
    }
}

执行结果:

执行之后就会发现在服务器上多了一个“CodeFirstDb”数据库:

EF学习和使用(三)Code First_第3张图片



三种模型的比较:

EF学习和使用(三)Code First_第4张图片



上图非常清晰的描述了,三种模式的适用环境以及各自的特性,关于这三种方式并没有什么优劣,在应用的时候考虑项目本身的情况决定即可。但值得一说的是CodeFirst的特性:运行时自动创建数据库。这一特性恰恰能够满足互联网软件多租户(云)的需要,后续博客中会具体说明。





代码下载

你可能感兴趣的:(EF学习和使用(三)Code First)