有二年没关注EF,今天无意试了下发现跟主流的Hibernate等ORM框架越来越接近了,先看下Entity类的定义:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EFSample.Model
{ [Table("T_ORDER")]
public class Order
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { set; get; } [StringLength()]
[Column("CUSTOMER_NAME")]
public String CustomerName { set; get; } [Column("AMOUNT")]
public decimal Amount { set; get; } public virtual ICollection<OrderItem> OrderItems { set; get; } }
}
 using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; namespace EFSample.Model
{
[Table("T_ORDER_ITEM")]
public class OrderItem
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { set; get; } [ForeignKey("Order")]
[Column("ORDER_ID")]
public int OrderID { set; get; } [StringLength()]
[Column("PRODUCT_NAME")]
public String ProductName { set; get; } [Column("PRICE")]
public Decimal Price { set; get; } [Column("QUANTITY")]
public int Quantity { set; get; } public virtual Order Order { set; get; } }
}

光看Attribute,已经跟Hibernate的Annotation很相似了。

配置文件:

 <?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="entityFramework"
type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</configSections> <entityFramework>
<contexts>
<context type="EFSample.DAL.OrderContext, EFSample" disableDatabaseInitialization="false">
<databaseInitializer type="EFSample.DAL.OrderInitializer, EFSample" />
</context>
</contexts>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v11.0" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
</providers>
</entityFramework> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.1" />
</startup> <connectionStrings>
<!--连接字符串,使用SQLSERVER LocalDb-->
<add name="MyConn" connectionString="Data Source=(LocalDb)\v11.0;Initial Catalog=OrderDatabase;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings> </configuration>

注:LocalDb在开发阶段很方便,但是试用中有一个小问题,如果把生成的mdf物理文件删除后,再次运行总是报错(不知道是不是个别现象),只能把Initial Catalog=OrderDatabase中的文件名改成其它名称(比如:Catalog=OrderDb),才能正常运行。

此外,NuGet Package Manager工具搞得象java的maven一样,可以自动联机下载所需的依赖项,Tools->NuGet Package Manager

输入

Install -Package EntityFramework

就能自动向project添加相关的dll引用

DbContext

 using EFSample.Model;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions; namespace EFSample.DAL
{
public class OrderContext:DbContext
{
public OrderContext() : base("MyConn") { } public DbSet<Order> Orders { set; get; } public DbSet<OrderItem> OrderItems { set; get; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
}

示例代码:

 using EFSample.DAL;
using EFSample.Model;
using System;
using System.Collections.Generic;
using System.Linq; namespace EFSample
{
class Program
{
static void Main(string[] args)
{
using (var db = new OrderContext())
{ //直接执行Sql语句
db.Database.ExecuteSqlCommand("delete from t_order"); var orders = new List<Order>(){
new Order{ CustomerName="jimmy.yang",Amount=, OrderItems=new List<OrderItem>(){
new OrderItem(){ Price=, Quantity=, ProductName="Mobile"}
}},
new Order{ CustomerName="杨俊明",Amount=, OrderItems=new List<OrderItem>(){
new OrderItem(){ Price=, Quantity=, ProductName="架构之美"}
}}}; //批量添加记录
db.Orders.AddRange(orders); //提交到db
db.SaveChanges(); //查询
var query = db.Orders.Where(c => c.CustomerName == "Jimmy.yang").AsQueryable(); //输出Sql语句
Console.WriteLine(query.ToString()); List<Order> orderEntities = query.ToList(); foreach (var order in orderEntities)
{
Console.WriteLine(String.Format("ID:{0}/CustomerName:{1}/Amount:{2}/ItemCount:{3}", order.ID, order.CustomerName, order.Amount,order.OrderItems.Count));
}
} Console.WriteLine("ok!");
Console.Read();
}
}
}

输出:

SELECT
[Extent1].[ID] AS [ID],
[Extent1].[CUSTOMER_NAME] AS [CUSTOMER_NAME],
[Extent1].[AMOUNT] AS [AMOUNT]
FROM [dbo].[T_ORDER] AS [Extent1]
WHERE N'Jimmy.yang' = [Extent1].[CUSTOMER_NAME]

ID:9/CustomerName:jimmy.yang/Amount:200/ItemCount:1
ok!

对Oracle的支持

MS默认并没有提供EF对Oracle的支持,需要到Oracle官网下载 http://www.oracle.com/technetwork/topics/dotnet/downloads/index.html

下载比较慢,耐心等待,完成后,一路Next即可。

注意:tnsnames.ora文件的配置,一般在x:\app\client\Administrator\product\12.1.0\client_1\Network\Admin 目录下,参考内容如下:

 XE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.187.128)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)

然后在vs中创建ADO.NET Entity Data Model时就能连接到Oracle db了,目前尚不支持Code-First,只能使用EF5,估计EF6要等明年才会正式发布
使用细节,可参考官网教程:http://www.oracle.com/webfolder/technetwork/tutorials/obe/db/dotnet/EntityFrameworkOBE/EntityFrameworkOBE.htm#t10

Sequence的处理:

Oracle中没有自增主键,msdn和oracle建议用trigger+sequence来处理自增主键的问题,即:insert前写个触发器,检测主键是否为空,如果为空,则将sequece.nextval赋值给它,参见:https://social.msdn.microsoft.com/Forums/th-TH/73453344-bbb9-4904-b77a-a9ba807dcfd2/oracle-e-entityframework?forum=mvcpt

示例代码:

 create sequence S_CD_TIPO minvalue 1 maxvalue 9999999 start with 1 increment by 1;

 create or replace trigger tp_procedimento_trigger
before insert on tp_procedimento for each row
begin
if :new.cd_tipo is null then select s_cd_tipo.nextval into :new.cd_tipo from dual;
endif;
end;

但我个人并不喜欢这种做法,感觉对db有点“侵入”,我比较喜欢在c#代码层掌控一切的感觉,如果大家跟我有一样的癖好,可以这么干:

 using System;
using System.Data;
using System.Data.Entity; namespace EntityFrameworkTest
{
public static class SequenceHelper
{
public static int GetNextVal(this DbContext db,String sequenceName) {
if (db.Database.Connection.State != ConnectionState.Open) {
db.Database.Connection.Open();
}
var cmd = db.Database.Connection.CreateCommand();
cmd.CommandText = String.Format("select {0}.nextval from dual", sequenceName);
cmd.CommandType = CommandType.Text; int result = ;
int.TryParse(cmd.ExecuteScalar().ToString(),out result); return result;
}
}
}

对DbContext写一个扩展方法,手动传入Sequence名称,然后在添加记录时,这样用:

 using System;
using System.Linq; namespace EntityFrameworkTest
{
class Program
{
static void Main(string[] args)
{
using (MyDbContext db = new MyDbContext())
{
//insert
T_BAS_AGENT newAgent = new T_BAS_AGENT();
newAgent.AGENT = "XYZ";
newAgent.CYEAR = ;
newAgent.RECID = db.GetNextVal("SEQ_T_BAS_CARRIER");
db.T_BAS_AGENT.Add(newAgent);
db.SaveChanges(); //query
var findAgent = db.T_BAS_AGENT.SingleOrDefault(c => c.RECID == newAgent.RECID);
Console.WriteLine(string.Format("{0}/{1}/{2}", findAgent.RECID, findAgent.AGENT, findAgent.CYEAR)); } Console.Read();
}
}
}

.NET:Entity Framework 笔记的更多相关文章

  1. Entity Framework笔记(一)

    最近在看MVC方面的资料,看了几个教程都在使用Entity Framework做数据持久化.之前也听说过这个东西,在微软的网站上看过一个演示视频,但都没怎么去仔细研究.MVC的东西太庞大了,先慢慢熟悉 ...

  2. Entity Framework 笔记(一)

    Entity Framework概述 EF是一个对象关系映射(ORM)框架,允许开发人员使用特定于域的对象关系型数据,开发人员通常不需要编写大量的数据访问代码.使用EF,开发者可以利用LINQ进行查询 ...

  3. Entity Framework笔记(二)

    前几日学习了在VS2010Console项目中使用Entity Framework,并且使用Code First模式.通过编写Model类,来生成数据库对应的表.并且,往表中写入数据以及获取表中的所有 ...

  4. Entity Framework 学习笔记(2)

    上期回顾:Entity Framework 学习笔记(1) Entity Framework最主要的东西,就是自己创建的.继承于DbContext的类: /// <summary> /// ...

  5. Entity Framework学习笔记

    原文地址:http://www.cnblogs.com/frankofgdc/p/3600090.html Entity Framework学习笔记——错误汇总   之前的小项目做完了,到了总结经验和 ...

  6. Entity Framework 6 学习笔记2 — 增、删、改、显示简单代码示例

    前言 通过 “Entity Framework 6 学习笔记1 — 介绍和安装方法”文章我相信大家对EF的安装应该没什么问题了,整体安装还是比较简单的,只需要通过Nuge搜索EF然后安装就可以了,这也 ...

  7. ADO.NET Entity Framework学习笔记(3)ObjectContext

    ADO.NET Entity Framework学习笔记(3)ObjectContext对象[转]   说明 ObjectContext提供了管理数据的功能 Context操作数据 AddObject ...

  8. .NET 5学习笔记(10)——Entity Framework Core之切换SQLServer和SQLite

    上一篇我们梳理了CodeFist的一般流程,本篇我们讨论如何在一套代码中,支持SQL Server和SQLite的切换.同时从本篇开始,我们从.NET Core 3.1 迁移到.NET 5.相信.NE ...

  9. MVC中使用Entity Framework 基于方法的查询学习笔记 (一)

    EF中基于方法的查询方式不同于LINQ和以往的ADO.NET,正因为如此,有必要深入学习一下啦.闲话不多说,现在开始一个MVC项目,在项目中临床学习. 创建MVC项目 1.“文件”--“新建项目”-- ...

随机推荐

  1. PHP implode() 函数 把数组元素组合为字符串

    http://www.w3school.com.cn/php/func_string_implode.asp PHP implode() 函数 PHP String 函数 实例 把数组元素组合为字符串 ...

  2. SQL Server(二)——语句

    表的创建: 1.创建列(字段):列名+类型 2.设置主键列(primary key):能够唯一标识一条数据 3.设置唯一(unique):内容不能重复 4.外键关系:一张表(从表)其中的某列引用自另外 ...

  3. Mysql Error:1205错误诊断

    前两天遇到一个1205(ER_LOCK_WAIT_TIMEOUT)的错误,弄了半天终于找到原因,掌握原理+细心才能找到罪归祸首.下面我给大家分享下这个问题的分析处理过程,希望对大家有所帮助.接到sla ...

  4. jQuery简单入门(四)

    4.表单应用 表单是HTML的重要组成部分,在采集.提交用户输入的信息和显示列表数据等需求中有重要作用 表单应用 一个简单的表单HTML示例: <form action=”url” method ...

  5. Windows7 系统 CMD命令行,点阵字体不能改变大小以及中文乱码的问题

    之前装了oracle 11g后,发现开机速度竟然奇葩的达到了3分钟.经过旁边大神指点,说是因为oracle某个(具体不清楚)服务,在断网的时候会不断的ping网络,导致速度变慢.然后就关服务呗,然后一 ...

  6. JavaScript中产生标识符方式的演变

    本文记录下JS中产生标示符方式的演变,从ES5到ES6,ES5及其之前是一种方式,只包含两种声明(var/function),ES6则增加了一些产生标识符的关键字,如 let.const.class. ...

  7. Javascript字数统计

    字数统计功能,原理是给textarea添加onKeyup事件,事件读取textarea内容并获得长度,并赋值给统计字数的那个文本节点,这里有一点要注意的是添加onKeypress和onKeydown事 ...

  8. PHP读取超大文件的实例代码

    数据量大带来的问题就是单个文件很大,能够打开这个文件相当不容易,记事本就不要指望了,果断死机   去年年底的各种网站帐号信息的数据库泄漏,很是给力啊,趁机也下载了几个数据库,准备学学数据分析家来分析一 ...

  9. Team Foundation Server 15 功能初探

    1. 系统安装 1.1. 系统需求 新版的TFS的系统要求发生了很大的变化,主要包含: - 不再支持32位的操作系统,只支持64位操作系统 - 只支持SQL 2014和SQL Server 2016, ...

  10. 嵌入式Linux驱动学习之路(七)Linux内核启动流程

    编译的内核可能会很大,故这里可以压缩一下.而在内核文件中需要解压,所以就会有一段自解压代码. 在uboot启动内核的时候,调用了函数: thekernel(0,MACH_ID,params_addr ...