在上篇博文中,小编主要简单的介绍了一下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等,小编也没有这么快就开始接触,在接项目的过程中学习,再把学习到的知识运用到项目中,赶脚棒棒哒,档案管理项目,未完待续......

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

  1. EF下CodeFirst、DBFirst与ModelFirst分析

    EF4.1有三种方式来进行数据操作及持久化.分别是Database-First,Model-First,Code-first:1.Database First是基于已存在的数据库,利用某些工具(如Vs ...

  2. 饮一盏Bug留香,唱一曲项目飞扬

    沿途的风景    牵挂的项目    两情迢迢 学生档案管理项目在2月的末尾从稍带寒意的季节里完成了第一次迭代,验收的结果不尽善尽美,演示的功能也惨不忍睹,各种"关爱"的点评充斥耳旁 ...

  3. ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借

    ASP.NET MVC深入浅出系列(持续更新)   一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...

  4. .Net Core建站(2):EF Core+CodeFirst数据库迁移

    上一篇的话,说了下怎么使用EF7 实现 CodeFirst去生成数据库, 其实还有好多问题的,这次一点一点的解决吧,都挺简单,不过零零散散的,, 1.读取配置文件,获得链接字符串 2.使用数据库进行增 ...

  5. 跟我一起学.NetCore之EF Core 实战入门,一看就会

    前言 还记得当初学习数据库操作时,用ADO.NET一步一步地进行数据操作及查询,对于查询到的数据还得对其进行解析,然后封装返回给应用层:遇到这种重复而繁琐的工作,总有一些大神或团队对其进行封装,从而出 ...

  6. 使用.Net Core+EF7 CodeFirst(2)

    上一篇的话,说了下怎么使用EF7 实现 CodeFirst去生成数据库, 其实还有好多问题的,这次一点一点的解决吧,都挺简单,不过零零散散的,, 1.读取配置文件,获得链接字符串 2.使用数据库进行增 ...

  7. ORM系列之Entity FrameWork详解

    一. 谈情怀 从第一次接触开发到现在(2018年),大约有六年时间了,最初阶段连接数据库,使用的是[SQL语句+ADO.NET],那时候,什么存储过程.什么事务 统统不理解,生硬的将SQL语句传入SQ ...

  8. C# Note3:大话Ninject

    前言 之所以研究Ninject,是因为初入职在开发XX项目的ComponentService部分时用到了它,一下子发现了它的强大.渐渐地发现在项目中,有时会用到优秀的第三方开源库,这些都是前人智慧的结 ...

  9. 细说ORM之Entity FrameWork系列(被替换)

    一. 谈情怀 从第一次接触开发到现在(2018年),接近五年时间了,最初阶段连接数据库,使用的是[SQL语句+ADO.NET],那时候,什么存储过程.什么事务 统统不理解,生硬的将SQL语句传入SQL ...

随机推荐

  1. Object Relational Tutorial 对象关系教程

    The SQLAlchemy Object Relational Mapper presents a method of associating user-defined Python classes ...

  2. 谷歌发布 TensorFlow Serving

    TensorFlow服务是一个灵活的,高性能的机器学习模型的服务系统,专为生产环境而设计. TensorFlow服务可以轻松部署新的算法和实验,同时保持相同的服务器体系结构和API. TensorFl ...

  3. LeeCode

    No1. Given an array of integers, return indices of the two numbers such that they add up to a specif ...

  4. gcc创建静态库和共享库

    静态库和动态(共享)库静态库:编译程序在编译使用库提供的功能代码的程序时将代码复制到该程序然后编译成可执行程序,这种库成为静态库共享库:共享库比静态库的处理方式更加灵活,因而其产生的可执行文件更小,其 ...

  5. eclipse安装和配置Gradle插件

    配置: 首先下载Gradle:https://gradle.org/gradle-download/ 设置Gradle环境变量: GRADLE_HOME %GRADLE_HOME%\bin" ...

  6. c++自定义类型

    /* --自定义数据类型 结构体 共用体 共用体的数据成员在存储数据时共享存储空间,修改一个成员也会改变另一个成员的值 枚举型 如果要使变量只能使用有限的几个值,则应当使用枚举体.之所以叫枚举体,就是 ...

  7. ACM Piggy Bank

    Problem Description Before ACM can do anything, a budget must be prepared and the necessary financia ...

  8. Python实现爬取需要登录的网站完整示例

    from selenium import webdriver dirver = webdriver.Firefox() dirver.get('https://music.douban.com/') ...

  9. 【SSH系列】spring中为什么要使用IOC

    开篇前言 在前面的博文中,小编主要简单的介绍了spring的入门知识,随着学习的深入,我们知道spring最核心的两大技术,IOC和AOP,这两个技术也是spring最耀眼的地方,在后续的博文中小编将 ...

  10. Mac小技巧:快速查看指定应用程序的所有窗口

    我们知道在Mac中快速在系统所有程序中切换得快捷键为: cmd + tab 不过有时我们需要快速查看某一个程序的所有窗口,那又该如何呢? 以下方法在MacOS 10.12中测试成功! Mac默认该功能 ...