深入浅出EF之ModelFirst和DBFirst

在上篇博文中,小编主要简单的介绍了一下EF的一些基础知识,其中,小编蜻蜓点水的提了一下ModelFirst和DBFirst,ModelFirst先设计实体,然后根据模型生成数据库,DBFirst根据数据库生成模型,两个方向都是可以了,两个方向可以相互更新,比如新添加了实体,可以根据模型生成数据库,如果在数据库里面新添加了字段,我们可以从数据库更新模型。在介绍ModelFirst和DBFirst之前,我们先来解决两个问题,EF与linq
to sql的关系以及为什么使用linq to sql和EF。

EF与linq to sql的关系

linq  to sql 是微软ORM思想的一个具体化,EF也是它的一个具体化,那么,这两个产品有什么区别呢?Linq to Sql是ORM思想实现的一个轻量级的框架,EF是一个重量级框架;Linq to Sql和EF的一个重要的区别就是,Linq to Sql只能针对于SQL Server数据库,而EF可以针对于很多的数据库(Oracle,SQL Server等),也就是说EF是跨数据库的,不要小看这一点,在实际的开发中,非常的实用,举个简单的小例子,还记我们敲的VB.NET版本的机房收费系统么,其中涉及到了数据访问层,如果出于某种原因,我们换了数据库,那么,我们就需要重新编写数据访问层,如果我们在创机房收费系统这个项目的时候,使用了linq
to sql,更换了数据库linq to sql框架就需要重新进行大量的改动,如果使用了EF框架,那么我们只需要改动其中的配置文件就可以了,不需要修改程序中的代码。

为什么使用linq to sql和EF

这个问题,也关乎我们的D层,还记得敲机房收费系统的时候,我们会抽出来一个sqlhelper类,这个类实现了对数据库的增删改查,然后,我们的再创建相应的D层类,这些类方法的功能,其实都差不多,唯一不同的就是sql,从这里我们可以看到,我们的D层的问题,那就是,我们重复性的书写一些不必要的类或者方法,解决这个方法就需要慢慢的抽象,抽象出共有的东西,像:DataTable装换为实体集,操作数据库的几类方法(注意其参数),然后将其一整合,这个大致就是我们所属的ORM思想实现的雏形了,当然,上面所说的那些东西,Linq
to Sql或EF这些框架已经帮助我们实现了,我们只需要使用它们提供的方法就行了,从这里我们也可以看到,如果我们使用这些框架,我们程序员在编程的时候,几乎不需要管理D层的东西,只需要关注业务的实现就可以了。

接下来,小编就来简单的介绍一下ModelFirst,ModelFirst先设计实体,然后根据模型生成数据库,如下图所示,

我们可以再图中空白处右击添加实体,还可以新增标量属性,以及添加关联。接着,我们可以根据上面的实体生成数据库,如下图所示:

生成的代码如下所示:

<span style="font-size:18px;"><span style="font-size:18px;">-- --------------------------------------------------
-- Entity Designer DDL Script for SQL Server 2005, 2008, 2012 and Azure
-- --------------------------------------------------
-- Date Created: 01/28/2015 15:43:19
-- Generated from EDMX file: C:\Users\Flower\Desktop\EFDemo\ModelFirstDemo\DataModel.edmx
-- --------------------------------------------------

SET QUOTED_IDENTIFIER OFF;
GO
USE [ModelFirstDemoDb2];
GO
IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo]');
GO

-- --------------------------------------------------
-- Dropping existing FOREIGN KEY constraints
-- --------------------------------------------------

IF OBJECT_ID(N'[dbo].[FK_CustomerOrder]', 'F') IS NOT NULL
    ALTER TABLE [dbo].[Order] DROP CONSTRAINT [FK_CustomerOrder];
GO

-- --------------------------------------------------
-- Dropping existing tables
-- --------------------------------------------------

IF OBJECT_ID(N'[dbo].[Customer]', 'U') IS NOT NULL
    DROP TABLE [dbo].[Customer];
GO
IF OBJECT_ID(N'[dbo].[Order]', 'U') IS NOT NULL
    DROP TABLE [dbo].[Order];
GO

-- --------------------------------------------------
-- Creating all tables
-- --------------------------------------------------

-- Creating table 'Customer'
CREATE TABLE [dbo].[Customer] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [CusName] nvarchar(32)  NULL,
    [SubTime] datetime  NOT NULL,
    [DelFlag] smallint  NULL
);
GO

-- Creating table 'Order'
CREATE TABLE [dbo].[Order] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [OrderContent] nvarchar(max)  NOT NULL,
    [CustomerId] int  NOT NULL
);
GO

-- Creating table 'UserInfo'
CREATE TABLE [dbo].[UserInfo] (
    [Id] int IDENTITY(1,1) NOT NULL
);
GO

-- --------------------------------------------------
-- Creating all PRIMARY KEY constraints
-- --------------------------------------------------

-- Creating primary key on [Id] in table 'Customer'
ALTER TABLE [dbo].[Customer]
ADD CONSTRAINT [PK_Customer]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- Creating primary key on [Id] in table 'Order'
ALTER TABLE [dbo].[Order]
ADD CONSTRAINT [PK_Order]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- Creating primary key on [Id] in table 'UserInfo'
ALTER TABLE [dbo].[UserInfo]
ADD CONSTRAINT [PK_UserInfo]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- --------------------------------------------------
-- Creating all FOREIGN KEY constraints
-- --------------------------------------------------

-- Creating foreign key on [CustomerId] in table 'Order'
ALTER TABLE [dbo].[Order]
ADD CONSTRAINT [FK_CustomerOrder]
    FOREIGN KEY ([CustomerId])
    REFERENCES [dbo].[Customer]
        ([Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;

-- Creating non-clustered index for FOREIGN KEY 'FK_CustomerOrder'
CREATE INDEX [IX_FK_CustomerOrder]
ON [dbo].[Order]
    ([CustomerId]);
GO

-- --------------------------------------------------
-- Script has ended
-- --------------------------------------------------</span></span>

接着我们来看一个具体的例子,ModelFirst关联实体的插入操作代码如下所示:

<span style="font-size:18px;"><span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ModelFirstDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            DataModelContainer db = new DataModelContainer();
            #region  Model First 关联实体的插入操作
            Customer customer = new Customer();
            customer.CusName = "呵呵";
            customer.DelFlag = 0;
            customer.SubTime = DateTime.Now;

            Order order = new Order();
            order.OrderContent = "Flower";

            //给导航属性赋值
            //order.CustomerID= customer.ID;
            order.Customer = customer;

            Order order2 = new Order();
            order2.OrderContent= "Flower2"; 

            order.CustomerID= customer.ID;
            order2.Customer = customer;

            db.Customer.Add(customer);
            db.Order.Add(order);
            db.Order.Add(order2);

            db.SaveChanges();
            #endregion
        }
    }
}</span></span>

接着,我们来看一下DBFirst,根据数据库生成模型,我们具体来看下面一段代码:

<span style="font-size:18px;"><span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;  

namespace EF.EntityFrameworkDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            #region 添加实体
            ////创建上下文对象
            //DBFirstEntities dbFirst = new DBFirstEntities();
            ////操作实体
            //T_Customer customer = new T_Customer();
            //customer.CusName = "新添用户";
            ////附加在上下文
            //dbFirst.T_Customer.AddObject(customer);
            ////保存
            //dbFirst.SaveChanges();
            #endregion  

            #region 删除实体
            ////1、创建上下文对象
            //DBFirstEntities dbFirst = new DBFirstEntities();
            ////2、创建实体
            //T_Customer customer = new T_Customer();
            //customer.ID = 9;
            ////3、将实体附加到上下文里面来进行管理
            //dbFirst.T_Customer.Attach(customer);
            ////修改实体的状态
            //dbFirst.ObjectStateManager.ChangeObjectState(customer, EntityState.Deleted);
            ////4、上下文操作数据库
            //dbFirst.SaveChanges();
            #endregion  

            #region 修改实体
            ////1、创建访问数据库的上下文对象
            //DBFirstEntities dbFirst = new DBFirstEntities();
            ////2、修改对象
            //T_Customer customer = new T_Customer();
            //customer.ID = 4;
            //customer.CusName = "用户4_修改后2";
            ////3、附加到数据库
            //dbFirst.T_Customer.AddObject(customer);
            ////修改对象状态
            //dbFirst.ObjectStateManager.ChangeObjectState(customer, EntityState.Modified);
            ////4、上下文更新数据库
            //dbFirst.SaveChanges();
            #endregion  

            #region 查询
            DBFirstEntities dbFirst = new DBFirstEntities();  

            foreach (var item in dbFirst.T_Customer)
            {
                Console.WriteLine(string.Format("ID:{0}  Name:{1}",item.ID,item.CusName));
            }
            #region linq表达式
            T_Customer cs = (from customer in dbFirst.T_Customer where customer.ID == 2 select customer).SingleOrDefault();
            Console.WriteLine("ID:{0}  Name:{1}",cs.ID,cs.CusName);
            #endregion  

            #endregion  

            Console.ReadKey();
        }
    }
}
</span></span>

ModelFirst和DBFirst两种方式,都可以达到我们想要的效果,实现同样的目的,两个方法可以相互更新,最后小编简单的来介绍一下延迟加载,延迟加载也可以叫做按需加载,可以分两方面来理解,一方面指暂时不需要该数据,不用在当前马上加载,而可以推迟到使用它时再加载;另一方面指不确定是否将会需要该数据,所以暂时请不要加载,待确定需要后再加载它。延迟加载是一种很重要的数据访问特性,可以有效地减少与数据源的交互(注意,这里所提的交互不是指交互次数,而是指交互的数据量),从而提升程序性能。在EF中有两种延迟加载,具体代码如下所示:

<span style="font-size:18px;"><span style="font-size:18px;">using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ModelFirstDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            DataModelContainer db = new DataModelContainer();
            #region  Model First 关联实体的插入操作
            Customer customer = new Customer();
            customer.CusName = "呵呵";
            customer.DelFlag = 0;
            customer.SubTime = DateTime.Now;

            Order order = new Order();
            order.OrderContent = "Flower";

            //给导航属性赋值
            order.CustomerID= customer.ID;
            order.Customer = customer;

            Order order2 = new Order();
            order2.OrderContent= "Flower2"; 

            order.CustomerID= customer.ID;
            order2.Customer = customer;

            db.Customer.Add(customer);
            db.Order.Add(order);
            db.Order.Add(order2);

            db.SaveChanges();
            #endregion

            #region 补充另外一个汇总查询方式:Lambda表达式
            Lambda表达式和linq表达式在编译阶段之后生成的IL代码是一样的
            var item = (from c in db.Customer
                        where c.Id == 2
                        select c).FirstOrDefault();
            List<string> list = new List<string>();
            list.FindAll()
            Function<Customer,bool>
            lambda的方式
            var itemLambda = db.Customer.Where<Customer>(c=>c.Id==1).FirstOrDefault();
            Console.WriteLine(itemLambda.CusName);
            #endregion

            #region 延迟第一种
            使用linq或者lambda表达式查出来的数据,只有使用的时候才回去真正的查询数据
            var items = from c in db.Customer
                        where c.Id < 10
                        select c;
            foreach (var customer in items)
            {
                Console.WriteLine(customer.Id);
            }

            IQueryable
            foreach (var customer in items)
            {
                Console.WriteLine(customer.Id);
            }
            #endregion

            #region 第二种延迟加载
            var customers = from c in db.Customer
                            select c;
            foreach(var cus in customers)
            {
                Console.WriteLine(cus.Id + "------");
                foreach (var order in cus.Order)
                {
                    Console.WriteLine(order.Id);

                }
                Console.WriteLine("------");
            }

            #endregion

            #region 查询部分列的数据
            只查询表中的部分列的数据
            var items = from c in Customer
                        where c.Id < 100
                        select new { id = c.Id, CusName = c.CusName, count = 0, orderCount = c.Order.Count() };
            foreach (var item in items)
            {
                Console.WriteLine(item.CusName + "------" + item.orderCount);
            }
            #endregion

            #region IQuerable接口跟其他集合的区别
            var items = (from c in db.Order
                         where c.Id < 2
                         select c).ToList();
            foreach (var order in items)
            {
                Console.WriteLine(order.Id);

            }
            #endregion
            Console.ReadKey();

        }
    }
}
</span></span>

小编寄语:该博文,小编主要介绍了一些EF的基础知识,分别从三个大方面对EF进行详细介绍,第一个方面:EF与linq to sql的关系以及为什么要使用EF与linq  to sql,第二方面,介绍了一下ModelFirst和DBFirst,最后介绍了一下延迟加载,对于EF的相关知识,小编刚刚接触,理解的还是很浅,有不同意见的小伙伴可以一起讨论交流哦,常常想,如果不是因为缘分,如果不是因为接受了项目什么mvc、EF、linq等,小编也没有这么快就开始接触,在接项目的过程中学习,再把学习到的知识运用到项目中,赶脚棒棒哒,档案管理项目,未完待续......

时间: 2025-01-19 21:57:31

深入浅出EF之ModelFirst和DBFirst的相关文章

EF下CodeFirst、DBFirst与ModelFirst分析

通过项目,我们了解到EF框架有三种数据持久化的方式,也就是标题中我所提到的三种.那么这些方式之间又有什么联系和区别呢? 篇幅原因,本篇博客不再分别介绍每种方法如何实现的了,大家用的时候可以去Sou~一下. 先分别介绍一下这三种方法的联系: 1.Database First是基于已存在的数据库,利用某些工具(如VS提供的EF设计器)创建实体类,数据库对象与实体类的匹配关系等,你也可以手动修改这些自动生成的代码及匹配文件.也就是从一个数据库开始,然后生成实体框架和相应代码. 2.Model Firs

EF之ModelFirst实体先行

继上篇博文中写到了DBFirst,下面就来讲讲关于ModelFirst知识,ModelFirst顾名思义,实体先行!      适用于在设计实体初期, 没有数据库表的原型,这样开发者在设计实体的同时可以生成数据库表,一举两得.下面就来讲讲ModelFirst的步骤: 首先建立一个控制台应用程序(和DBFirst的步骤相似) 新建如下图: 添加新建项-选择ADO.NET实体数据模型: 这里和DBFirst不一样,因为ModelFirst没有数据库,选择空模型:  如下图所示: 在空白处右键,选择实

【EF】ModelFirst实体优先

一.前言 在前文中我们介绍了DBFirst,它要求要现有数据库, 然后通过EF映射创建实体.非常简单易学.下面给大家介绍另外一种--ModelFirst,实体优先. 二.内容介绍 Model First 是先利用某些工具(如VS的EF设计器)设计出可视化的实体数据模型及他们之间的关系,然后再根据这些实体.关系去生成数据库对象及相关代码文件. 通过实战演练来更好的展示: 三.实战演练 首先打开VS2012 ,选择控制台程序: 图一 选择控制台程序 第一步 添加实体 然后在项目中添加ADO实体模型:

.NET EF Core2.0 (DBFirst)使用与配置

本文环境:vs2017 win10 .NET CORE 2.14 其次,如果你是Windows7系统 那么需要升级你的Windows PowerShell到3.0+的版本 然后你需要安装相关的工具包,从NuGet下载即可如下图: 为了方便你们复制..我列一下: Microsoft.EntityFrameworkCore EF框架核心包 Microsoft.EntityFrameworkCore.SqlServer sql数据库需要,类似的还有mysql.oracle. Microsoft.Ent

三年前,故事这样开始;三年后,故事这样延续---2015年终总结

 含苞待放的蕊,开出尘埃落定的美 人生的路途,自从小编学了计算机之后,喜欢这样来描述,人生就好像是一个开发软件的一个流程,从需求分析到运行维护,需求一次又一次的变更,人生的经历一次又一次在过程中丰富,人生的路又像季节的更迭,有微风也有细雨,花含苞待放之后化作春泥更护花,生命的年轮不停地转动着,缘深缘浅,缘聚缘散,不断地经历.也许生命本身的意义就在于,不断的去经历,不断的去成长.走过的路很漫长,也给自己一个交代,曾经的迷茫,曾经的伤感失落,都在沉淀后显得那么清澈.那一个个走过生命的故事,就像吟唱在

伴着代码,那个女孩儿慢慢长大

伴着代码,那个女孩儿慢慢长大 岁月荏苒,浅夏将一种极致的婉约,律动在代码的世界里,小编轻轻走过一个又一个项目,感恩这份美好.每个波澜不惊的日子,都散发着恬淡的香,那是时光沉淀的馨香,那是代码独有的味道,小编倔强认为,最长久的幸福,是来自平凡日子里点点滴滴滴的积累.繁华落尽终究是平淡,代码的美,不在于绚丽,而贵在坚持:IT的美,不在于轰轰烈烈,而在于平凡的坚守,温暖的陪伴.阳光依然灿烂,明天依然向往.秉持着心中的梦想去激情燃烧.这个八月,与阳光同行,带梦想前行,努力抵达内心向往已久的目的地. 不知

EF浅析及示例分析

数据作为软件的重要组成部分,它的存储和传递是每个软件必须考虑的事情.EF作为web应用程序开发过程中常用的数据处理解决方案,它是如何工作的,它的特点是什么?本文就此做个简单介绍. 最开始的时候,数据量比较小,并且没有涉及到数据库,我们使用变量作为载体,保存和传递数据,使用作用域的方式来界定变量的作用范围:这种方式的坏处就是,每个数据都需要一个变量,并且我们需要了解每个变量的作用域才能正确的使用它们. 接触到数据库以后,变量已经不能满足大批量数据的存储和传递,这时候DataTable表和实体出现了

实体框架- Entity Framework 基础篇

以前写数据层D层的时候里面有好多的SQL语句,如何省略到繁琐的SQL语句,微软提供了一种很好的方式-实体框架-Entity Framwork.一种对象映射机制,支持.NET开发人员使用域特定对象来出来关系数据,消除了对开发人员通常需要编写的大部分数据访问代码的需求. ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案.实体框架Entity Framework是ADO.NET中的一组支持开发面向数据的软件

从0开始,一起搭框架、做项目(2)创建数据库和数据模型

简述 我们创建一个数据库然后生成数据模型,添加ADO.NET实体数据模型,这里呢常用的有两种方式,一种是DbFirst,一种是CodeFirst,为了简便,我们使用DbFirst.有基础的朋友可以使用CodeFirst,对项目没有影响的. 项目准备 我们用的工具是:VS 2013 + SqlServer 2012 + IIS7.5 希望大家对ASP.NET MVC有一个初步的理解,理论性的东西我们不做过多解释,有些地方不理解也没关系,会用就行了,用的多了,用的久了,自然就理解了. 项目开始 一.