热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

一步一步学EntityFrameWork4(1)

本人在学习EF4时,读了很多书,走了很多弯路,最后发现其实EF4很简单,结合Linq,可以实现非常简单的添查删改操作。下面以一个实例为例对EF4的使用作一解析,希望大家在此少走弯路。本文采用较为成熟的

本人在学习EF4时,读了很多书,走了很多弯路,最后发现其实EF4很简单,结合Linq,可以实现非常简单的添查删改操作。下面以一个实例为例对EF4的使用作一解析,希望大家在此少走弯路。本文采用较为成熟的Database First模式,从数据库生成模型,然后使用T4模板生成POCO类代码,最后使用控制台程序进行调用。

1、数据库准备

本文选择的数据库是一个在实际工作中非常常用的数据库, 构造如下:

各个表的结构和数据类型如下:

  • ProductUnit表:产品单位

  • Products表:产品信息表

  • ProductBigType:产品大类

  • ProductSmallType:产品小类

依照上述步骤在Sql Server Management Studio编写完成后,就可以准备进行调用了。

2.准备相关工具

相信手边VS已经安装完毕,还要下载Entity Framework 4.x来进行安装,除此以外还需要一个重要的工具:

EF4.x POCO Entity Generator for C#,想要安装这一工具,点击VS的工具菜单下的扩展管理器,,,,在搜索框中搜索POCO字样就可以找到。这个工具实际上是一个T4模板,通过它可以为我们自动生成POCO式的实体类以及对ObjectContext的引用。

3、生成实体的POCO类

1)首先新建一个控制台项目,命名为ProdouctEFDemo;  

2) 在该项目的根结点上右键单击,在弹出的菜单里选择添加→新建文件夹,新建一个命名为Models的文件夹,数据模型将放在这里。

3)在Models文件夹上右键单击,在弹出的菜单里选择添加→新建项,在弹出的对话框中选择ADO.Net实体数据模型,并将其命名为ProductEFDemo.edmx;单击添加按钮继续;

pic7

image

4)选择“从数据库生成”,单击下一步继续;

image

5)点击新建连接,找到需要生成实体的数据库(这一步就不用演示了吧!)

注意勾选“将App.Config中的实体连接设置另存为”选项,本对话框中的ProductsEntities就是未来实体对象的类名,建议不要更改。观察一下实体连接字符串,哇好复杂,不用管他。操作完成后单击下一步继续:

image

6)选择全部的表,并注意勾选“在模型中加入外键列”,这一选项是EF4新增的,在实际应用中有很多好处,特别是在构建模型时,单击完成按钮就会在Models文件夹下生成实体数据模型:

注意检查VS的“输出”窗口,是否提示有生成错误等信息,如果有错误,就需要从“错误列表”窗口查看是什么出了错,一一解决。最常见的错误是表没有设置主键列,这会导致在进行数据插入时出现一些莫名其妙的错误,所以有关的检查在这一步都要完成,否则后面出了错很难调试。当然高手也可以通过手工悠edmx文件来解决(这个文件实际上就是一个XML文件),但是既然有可视化编辑器,为什么不让问题消失在萌芽中呢?

7)现在进入最高级的一步:生成实体类。VS默认已经有两个可供使用的实体类生成器,但个人觉得都不是很好用,没有生成POCO类,理解起来也困难。有了前面介绍的EF4.x POCO Entity Generator,问题迎刃而解。在VS中的ProductEFDemo.edmx的设计器界面任意的空白处点击右键,在弹出的菜单中选择“添加代码生成项”,在弹出的对话框选择EF4.x POCO Entity Generator,为其随便起一个名字:

image

点击添加后,Models文件夹下就出现了两个T4模板,并且同时自动运行T4生成器,为我们生成了所需要的实体POCO代码。你可以花一点时间研究一下这些代码,在这里因为篇幅原因,就不再拷贝代码了:
image

如果代码没有自动生成,可以在两个T4模板上分别点击左键,在弹出的菜单里选择“运行自定义工具”命令,可以得到同样的效果。

现在大功告成,可以动手进行我们的添查删改操作了。

4、向数据库添加测试数据:

为了简单起见,我们向数据库添加的数据符合这样的规则:如果字符串类型,内容为XX测试数据+序号,如果为decimal类型,内容为随机的double类型数据,如果是时间类型,内容为DateTime.Today;为此我们逐个向数据库添加数据,向数据库里添加数据的原则是:如果是一对多关系,先添加一的部分,再添加多的部分,否则多的部分会因为没有数据可用而引发异常,在本示例里,Product表是多的部分,而ProductUnit是一的部分,所以添加数据的顺序应为ProductUnit→ProductBigType→ProductSmallType→Product:

在项目中再添加一个文件夹,命名为Business,将我们进行添查删改的代码都放在里面,新建一个静态类InsertData,cs:

using System;using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProductEFDemo.Models;

namespace ProductEFDemo.Business
{
public static class InsertData
{
public static void AddProudctUnit()
{
for (int i = 0; i <10; i++)
{
var productUnit = new ProductUnit
{
ProductUnitId=Guid.NewGuid(),
ProductUnitName = String.Format("产品单位测试数据{0}",i.ToString())
};
using (var ctx = new ProductsEntities())
{
ctx.ProductUnit.AddObject(productUnit);
ctx.SaveChanges();
}

}

}
}
}

好了,基本的ProductUnit的数据录入问题得到圆满解决。这里对代码作一个解释:

在命名空间务必要添加对ProductEFDemo.Models的引用,因为实体的POCO类,ObjectContext类都在这呢!

然后就可以自由地调用相关的类了,注意这句:

using (var ctx = new ProductsEntities()) { ctx.ProductUnit.AddObject(productUnit); ctx.SaveChanges(); }

适用于所有情况,其中ctx是ObjectContext类的实例,调用AddObject方法就可以将对象加入ObjectContext,然后再调用SaveChanges方法就可以将数据更新到数据库。是不是很简单?

如法泡制:

  public static void AddProductBigType()
{
for (int i = 0; i <10; i++)
{
var productBigType = new ProductBigType
{
ProductBigTypeId = Guid.NewGuid(),
ProductBigTypeName = String.Format("产品大类测试数据{0}", i.ToString())
};
using (var ctx = new ProductsEntities())
{
ctx.ProductBigType.AddObject(productBigType);
ctx.SaveChanges();
}

}
}

       public static void AddProductSmallType(Guid productBigTypeId)
{
for (int i = 0; i <10; i++)
{
var productSmallType = new ProductSmallType
{
ProductBigTypeId=productBigTypeId,
ProductSmallTypeId=Guid.NewGuid(),
ProductSmallTypeName = String.Format("产品小类测试数据{0}", i.ToString())
};
using (var ctx = new ProductsEntities())
{
ctx.ProductSmallType.AddObject(productSmallType);
ctx.SaveChanges();
}
}
}

public static void AddProduct(Guid productUnitId,Guid productSmallTypeId)
{
for (int i = 0; i <10; i++)
{
var rand = new Random();
var product = new Product()
{
ProductId=Guid.NewGuid(),
ProductName=string.Format ("产品名称测试数据{0}",i.ToString()),
ProductSmallTypeId=productSmallTypeId,
ProductUnitId=productUnitId,
ProductBasePrice=(decimal)(rand.NextDouble()*100),
ProductLosePrice=(decimal)(rand.NextDouble()*50)
};
using (var ctx = new ProductsEntities())
{
ctx.Product.AddObject(product);
ctx.SaveChanges();
}
}
}
SQL表生成代码下载:
/Files/qouoww/sql.zip

声明:本文系本人原创,版权归属作者和博客园共同所有,任何组织或个人不得随意转载,修改。需要转载请与本人联系:qouoww@163.com。

 


推荐阅读
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 本文介绍了[从头学数学]中第101节关于比例的相关问题的研究和修炼过程。主要内容包括[机器小伟]和[工程师阿伟]一起研究比例的相关问题,并给出了一个求比例的函数scale的实现。 ... [详细]
  • 本文介绍了如何将CIM_DateTime解析为.Net DateTime,并分享了解析过程中可能遇到的问题和解决方法。通过使用DateTime.ParseExact方法和适当的格式字符串,可以成功解析CIM_DateTime字符串。同时还提供了关于WMI和字符串格式的相关信息。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了游标的使用方法,并以一个水果供应商数据库为例进行了说明。首先创建了一个名为fruits的表,包含了水果的id、供应商id、名称和价格等字段。然后使用游标查询了水果的名称和价格,并将结果输出。最后对游标进行了关闭操作。通过本文可以了解到游标在数据库操作中的应用。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • 本文介绍了如何使用python从列表中删除所有的零,并将结果以列表形式输出,同时提供了示例格式。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 本文讨论了Kotlin中扩展函数的一些惯用用法以及其合理性。作者认为在某些情况下,定义扩展函数没有意义,但官方的编码约定支持这种方式。文章还介绍了在类之外定义扩展函数的具体用法,并讨论了避免使用扩展函数的边缘情况。作者提出了对于扩展函数的合理性的质疑,并给出了自己的反驳。最后,文章强调了在编写Kotlin代码时可以自由地使用扩展函数的重要性。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
author-avatar
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有