EntityFramework(1)基础概念与Database First

基本概念

EntityFramework是微软推出的一款ORM工具,关于ORM的概念请参考博客http://www.javashuo.com/article/p-dyrdltpl-dx.html。这篇文章对ORM进行很详细的介绍。简单的说,ORM是经过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。html

在.NET3.5以前咱们从数据库检索或者存储数据的方式常常都是ADO.NET。操做数据会经历以下步骤,打开数据库链接,建立一个数据集来获取或提交数据到数据库,将数据集中的数据转换为.NET对象。或者反过来应用业务规则。这是一个繁琐且重复的工做,或许会有一些Helper来帮助咱们解决数据库链接方面的工做,可是数据集到领域对象的过程是咱们须要一次次去映射的。因此,ORM工具就提供给了咱们操做业务对象,由ORM对咱们操做的对象进行数据库操做映射。EntityFramework就是这样的一种工具,咱们使用Linq操做领域对象,EntityFramework会帮咱们将对应操做转换为SQL语句,而后链接到数据库执行。这样咱们就能够在更高的抽象层面来处理数据,而且与传统应用程序相比,能够用更少的代码建立和维护面向数据的应用程序。关于EntityFramework的概念和介绍能够参考MSDN或者http://www.entityframeworktutorial.net/what-is-entityframework.aspx。以上部分概念也来源于此网站。另外,EntityFramework Core为EF垮平台版本。好了,下面进入EntityFramework的具体使用部分。数据库

EntityFramework的3中使用模式

EntityFramework有3中使用模式app

  1. DataBase First:从数据库开始,在数据库已经存在的状况下。经过数据库结构构建实体映射对象,并生成映射元数据
  2. Model First:使用EntityFramework提供给的模型建立工具建立数据模型与映射元数据,经过这些元数据信息建立数据库
  3. Code First:经过DDD建立领域对象并配置映射规则,数据迁移规则。EF会根据领域对象模型与映射规则来建立数据库

下面咱们依次来看看3种模式在实际的编码过程当中怎么使用,示例程序使用SQL Server2016数据库引擎,Northwind数据库。开发工具为VS2017。ide

1 Database First数据模型定义

1,建立控制台应用Demo.DatabaseFirst函数

2,安装EntityFramework Nuget包,示例程序版本为6.2.0工具

2

3,添加实体数据模型,在Data模板下选择ADO.NET实体数据模型,命名为DemoModel学习

image

4,由于咱们是从数据库生成实体数据模型,因此,咱们选择来自数据库的EF设计器开发工具

image

5,进行数据库配置,因为我这里以前配置过数据库,因此会有以前的链接信息,此处,咱们新建数据库链接,点击新建链接网站

image

6,配置数据链接,并选择数据库。在高级选项中,有关于链接配置的选项,能够根据须要修改。ui

image

7,配置完成后,点击下一步选择须要生成实体数据模型的表(视图,存储过程或者函数)

image

8,点击完成,此时,从数据库映射的实体数据模型已经生成。咱们能够看一下,在解决方案结构中,EF帮咱们新建了哪些文件,在配置文件中又帮咱们加入了哪些内容

image

DemoModel.edmx就是EF帮咱们生成的数据模型,双击以后,咱们能够看到咱们选中的表已经映射成为了实体数据模型。生成模型的规则是EF定义的模板文件(XXX.tt),不一样的EF版本有不一样的模板文件,咱们也能够自定义模板文件。咱们右键点击某个模型,能够看到以下图的菜单。从数据库更新模型,当数据库发生更改的时候,咱们能够经过点击此菜单来将数据库的更改映射到模型。表映射能够查看实体数据类型与表的映射,属性与列信息的映射信息等等。咱们也能够查看数据模型的属性,在空白处点击右键,选择属性。能够看到数据模型的选项,有数据库的链接字符串信息,是否延迟加载等等,能够根据需求自行更改配置。

image

实体关系:从edmx设计中能够看到,实体之间的链接线有1…*,*…*,0..1的关联属性,这些关系实际上映射的就是数据库中表之间的关系,也就是咱们常说的,一对一,多对多,一对多。实体数据模型会根据数据库中的主外键信息自动生成关系模型数据。选中链接线,右键查看属性,能够查看实体之间关系的具体信息。

导航属性:上面说了,实体与实体之间是存在关系的,那么怎么从一个实体去访问另一个与他有关系的实体呢,实际上咱们经过导航属性。导航属性实际上就是实现了从一个实体到另外一个关联实体的访问机制。

实体数据模型实际上包含了实体对象信息,数据库元数据信息,对象与数据库的映射信息。那么这些信息是在哪里定义的呢,咱们使用文本编辑工具打开DemoModel.edmx文件,能够看到edmx其实是一个xml文件,这个xml文件的主要节点以下

image

1,edmx:StorageModels(逻辑层SSDL):SSDL主要定义了数据库中表,列,关系,视图,函数等

2,emdx:ConceptualModels(概念层CSDL):CSDL主要定义了数据模型的实体类型,这些实体暴露给上层来操做实体数据

3,edmx:Mappings(映射层):SSDL与CSDL之间的关系映射

2 Database First数据模型操做

EntityFramework使用了上述的xml文件定义了,实体,数据库对象,与他们之间的关系。至此,咱们完成了EntityFramework的实体数据映射并分析了基本原理。定义数据模型的意义在于操做数据,下面咱们使用数据模型来进行数据的增删改查。咱们新建类CategoryServices,并添加AddCategory,UpdateCategory,DeleteCatetory,GetCatetories四个方法

2.1增长数据

public bool AddCategory(Category category)
        {
            using (NorthwindEntities context = new NorthwindEntities())
            {
                context.Categories.Add(category);

                return context.SaveChanges()>0;
            }
        }

2.2修改数据

public bool UpdateCategory(Category category)
        {
            bool reuslt = false;
            using (NorthwindEntities context = new NorthwindEntities())
            {
                Category currentCategory = context.Categories
                    .FirstOrDefault(parm => parm.CategoryID == category.CategoryID);
                if (currentCategory != null)
                {
                    currentCategory.Description = category.Description;
                    reuslt = context.SaveChanges() > 0;
                }

                return reuslt;
            }
        }

2.3删除数据

public bool DeleteCatetory(int id)
        {
            bool reuslt = false;
            using (NorthwindEntities context = new NorthwindEntities())
            {
                Category currentCategory = context.Categories
                    .FirstOrDefault(parm => parm.CategoryID == id);
                if (currentCategory != null)
                {
                    context.Categories.Remove(currentCategory);
                    reuslt = context.SaveChanges() > 0;
                }

                return reuslt;
            }
        }

2.4查询数据

public List<Category> GetCatetories()
        {
            using (NorthwindEntities context = new NorthwindEntities())
            {
                return context.Categories.ToList();
            }
        }

调用代码

class Program
    {
        static void Main(string[] args)
        {
            CategoryServices services = new CategoryServices();

            List<Category> categories = services.GetCatetories();
            categories.ForEach(parm => Console.WriteLine($"{parm.CategoryName}---{parm.Description}"));
            Console.WriteLine("---select---");

            Category category = new Category
            {
                CategoryName = "Microsoft",
                Description = "this is Microsoft"
            };

            bool result = services.AddCategory(category);
            Category categoryAdd = services.GetCatetories().LastOrDefault();
            Console.WriteLine($"{categoryAdd.CategoryName}---{categoryAdd.Description}");
            Console.WriteLine("---add---");

            Category categoryUpdate = new Category
            {
                CategoryID = categoryAdd.CategoryID,
                CategoryName = "Microsoft",
                Description = "this is Microsoft update"
            };

            bool updateResult = services.UpdateCategory(categoryUpdate);
            Console.WriteLine($"{categoryUpdate.CategoryName}---{categoryUpdate.Description}");
            Console.WriteLine("---update---");

            int catetoryId = categoryAdd.CategoryID;
            bool deleteUpdate = services.DeleteCatetory(catetoryId);
            Category categoryLast = services.GetCatetories().LastOrDefault();
            Console.WriteLine($"{categoryLast.CategoryName}---{categoryLast.Description}");
            Console.WriteLine("---delete---");

            Console.ReadLine();
        }
    }

执行结果

以下图执行结果,第一步咱们打印了全部的Category,第二步咱们添加一条Category,紧接着咱们修改了添加的这条数据,最后咱们删除这条数据。能够看到,增删改查操做完成。是否是感受操做数据库也能够像操做对象同样简单,便捷。

image

数据操做基本概念

DbContext:上面的实例中,咱们实例化了类型NorthwindEntities。这个在咱们配置数据库链接的时候输入的上下文名称。实际上,在EntityFramework帮助咱们生成数据模型时,也同时帮咱们生成了继承与DbContext类型的数据上下文,咱们这里是NorthwindEntities。那么数据上下文是什么呢。数据上下文实际是真实与数据库交互的桥梁。前面的章节咱们定义了对象,数据,映射,这些都是基础设施,也是基础结构。在操做数据时,好比添加数据。最终数据库能执行的操做只会是SQL语句,存储过程等。因此 ,数据上下文监测了咱们对实体类型的更改,在调用SaveChange时将咱们对上下文中实体的更改转换成SQL语句发送给数据库执行,咱们能够打开SQL Server监视工具来查看EntityFrameworkSaveChange后生成的SQL语句。因此,在了解了ORM的核心概念后,其实,若是咱们愿意,也能够本身实现一套ORM工具。

image

下面的代码就是EntityFramework生成的继承自DbContext的数据上下文。

namespace Demo.DatabaseFirst
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    
    public partial class NorthwindEntities : DbContext
    {
        public NorthwindEntities()
            : base("name=NorthwindEntities")
        {
        }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }
    
        public virtual DbSet<Category> Categories { get; set; }
        public virtual DbSet<CustomerDemographic> CustomerDemographics { get; set; }
        public virtual DbSet<Customer> Customers { get; set; }
        public virtual DbSet<Employee> Employees { get; set; }
        public virtual DbSet<Order_Detail> Order_Details { get; set; }
        public virtual DbSet<Order> Orders { get; set; }
        public virtual DbSet<Product> Products { get; set; }
        public virtual DbSet<Region> Regions { get; set; }
        public virtual DbSet<Shipper> Shippers { get; set; }
        public virtual DbSet<Supplier> Suppliers { get; set; }
        public virtual DbSet<Territory> Territories { get; set; }
    }
}

好了,至此,EntityFramework的基本概念和Database First基本操做已经完成,因为水平有限,若是在讲解过程当中有任何错误请留言告知,在学习与记录的过程与你们共同进步。下一篇会讲解EntityFramework的Model First。

相关文章
相关标签/搜索