Entity Framework DBContext 增删改查深度解析
Entity Framework DBContext 增删改查深度解析
有一段时间没有更新博客了,赶上今天外面下雨,而且没人约球,打算把最近对Entity Framework DBContext使用的心得梳理一下,早些时候在网上简单查过,对于最新版本的EF并没有类似的知识梳理类文章,希望对大家有所帮助。
1. 不要Code first, 也不要DB first
我为什么讨厌Code first和DB first呢?首先Code first是先写代码,数据库完全由代码生成,开发阶段尚可,一旦到了产品发布阶段,如果需要添加字段,我们总不能用 visual studio去生产环境上去更新数据库吧,听起来就很可怕。而且另外的一个问题自动是生成的数据库脚本也不可控,还不如自己提前设计好。DB first也好不了哪去,反向转过来的代码包含很多没有用的文件,而且数据库的更新还要重新走Model生成过程,简直无法理解为什么会有这样的设计。说了这么多,怎么解决呢?
数据库和领域模型分开设计,按照对应关系映射字段,使用自定义链接字串,既不使用领域模型生成数据库,也不用数据库生成领域模型,示例代码如下,SQL Code 以 Destinations和TTable表为例:
CREATE TABLE [DBO].[Destinations]
(
[DestinationId] [int] PRIMARY KEY NOT NULL,
[Name] [nvarchar](max) NULL,
[Country] [nvarchar](max) NULL,
[Description] [nvarchar](max) NULL,
[Photo] [varbinary](max) NULL
)
CREATE TABLE [TTT].[TTable]
(
[Id] [int] PRIMARY KEY NOT NULL,
[Name] [nvarchar](max) NULL
)
Model Class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace Model
{
public class Destination
{
public int DestinationId { get; set; }
public string Name { get; set; }
public string Country { get; set; }
public string Description { get; set; }
public byte[] Photo { get; set; }
public List<Lodging> Lodgings { get; set; }
} public class Lodging
{
public int LodgingId { get; set; }
public string Name { get; set; }
public string Owner { get; set; }
public bool IsResort { get; set; }
public Destination Destination { get; set; }
} public class TTable
{
public int Id { get; set; }
public string Name { get; set; }
}
}
Connect String:
<connectionStrings>
<add name="BAContext" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;Initial Catalog=DataAccess.BreakAwayContext;Integrated Security=SSPI;" providerName="System.Data.SqlClient" />
</connectionStrings>
DB Context:
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using Model; namespace DataAccess
{
public class TTableConfiguration : EntityTypeConfiguration<TTable>
{
public TTableConfiguration()
{
this.ToTable("TTable", "TTT");
}
} public class BreakAwayContext : DbContext
{ protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new TTableConfiguration());
} public BreakAwayContext(string connString) : base(connString)
{
}
public DbSet<Destination> Destinations { get; set; }
public DbSet<Lodging> Lodgings { get; set; }
public DbSet<TTable> TTables { get; set; }
}
}
2. 如果数据库的表的字段和领域模型的字段不对应,如何处理呢?比如本文的TTable表是在TTT Schema下面的, 而其他表示设计在DBO下面,最方便的方式是使用fluent API, 具体代码如请参见 TTableConfiguration Class和 OnModelCreating()方法,可配置的粒度非常细,比如可以配置领域模型和数据库的哪个Schema的哪张表的哪一列对应,本文是将TTable 类的数据库表配置为了TTT Schema下的TTable表,
public class TTableConfiguration : EntityTypeConfiguration<TTable>
{
public TTableConfiguration()
{
this.ToTable("TTable", "TTT");
}
}
3. 增删该查自带事物支持,具体代码如下,
public static int Insert()
{
var destination = new Destination
{
Country = "Chs",
Description = "Chs is the language package",
Name = "xsss"
};
using (var context = new BreakAwayContext(ConfigurationManager.ConnectionStrings["BAContext"].ConnectionString))
{
var rt = context.Destinations.Add(destination);
context.SaveChanges();
return rt.DestinationId;
}
} public static void Update(Destination destIn)
{
using (var context = new BreakAwayContext(ConfigurationManager.ConnectionStrings["BAContext"].ConnectionString))
{
var dest = context.Destinations.Where(a => a.DestinationId == destIn.DestinationId).Single();
dest.Name = destIn.Name;
context.SaveChanges();
}
} public static void Delete(int destId)
{
using (var context = new BreakAwayContext(ConfigurationManager.ConnectionStrings["BAContext"].ConnectionString))
{
var destination = new Destination() { DestinationId = destId };
context.Destinations.Attach(destination);
context.Destinations.Remove(destination); context.SaveChanges();
}
} public static Destination Query(int destId)
{
using (var context = new BreakAwayContext(ConfigurationManager.ConnectionStrings["BAContext"].ConnectionString))
{
IQueryable<Destination> dest = context.Destinations.Where(a => a.DestinationId == destId); return dest.Single();
}
}
4. 如果需要多个操作同时成功或者失败,需要手动开启事务,具体代码如下,
public static void TransactionOps()
{
using (var context = new BreakAwayContext(ConfigurationManager.ConnectionStrings["BAContext"].ConnectionString))
{
using (var dbContextTransaction = context.Database.BeginTransaction())
{
try
{
var destination = new Destination
{
Country = "Chs",
Description = "Chs is the language package",
Name = "xs2s"
}; var destId = context.Destinations.Add(destination); context.SaveChanges(); context.Destinations.Attach(destId);
context.Destinations.Remove(destId); context.SaveChanges(); dbContextTransaction.Commit();
}
catch (System.Exception ex)
{
dbContextTransaction.Rollback();
System.Console.WriteLine(ex.ToString());
}
}
}
}
5. 分页查询是网站设计的常用功能,一个简单的真分页查询方法如下如下所示,
public static List<Destination> QueryPaging<TKey>(int pageIndex, int pageSize, Expression<Func<Destination, bool>> whereLambda, Expression<Func<Destination, TKey>> orderBy)
{
using (var context = new BreakAwayContext(ConfigurationManager.ConnectionStrings["BAContext"].ConnectionString))
{
return context.Destinations.Where(whereLambda).OrderBy(orderBy).Skip((pageIndex - ) * pageSize).Take(pageSize).ToList();
}
}
总结
本文对最新版本的Entity Framework进行增删改查操作给出了详尽的解释,并且给出了数据库和领域模型代码分开设计的完整解决方案,同时介绍了手动数据库表和领域模型映射,数据库事务实现,分页查询等常用功能,希望对大家有所帮助。
Entity Framework DBContext 增删改查深度解析的更多相关文章
- ASP.NET中使用Entity Framework开发增删改查的Demo(EF增删改查+母版页的使用)
这里更多的是当作随身笔记使用,记录一下学到的知识,以便淡忘的时候能快速回顾 这里是该项目的第二部分, 第一部分 第二部分(当前部分) 大完结版本 此Demo是新建了一个音乐类型的web,然后使用母版页 ...
- AppBox升级进行时 - Entity Framework的增删改查
AppBox 是基于 FineUI 的通用权限管理框架,包括用户管理.职称管理.部门管理.角色管理.角色权限管理等模块. Entity Framework新增数据 以新增用户为例,作为对比,先来看下使 ...
- Entity FrameWork 5 增删改查 & 直接调用sql语句
class="brush:csharp;gutter:true;"> #region 1.0 新增 -void Add() /// <summary> /// 1 ...
- Entity FrameWork 5 增删改查 & 直接调用sql语句 ?
#region 1.0 新增 -void Add() /// <summary> /// 1.0 新增 /// </summary> static void Add() { / ...
- Entity Framework 简单增删改操作
前言 在 Entity Framework 简单查询操作 中主要是学习了在Entity Framework中的几种不同模式的查询操作,现在主要来学习一下简单的增加.删除.修改操作. 增加 在EF中添加 ...
- 使用Enitity Framework实现增删改查服务中的一些通用思路
添加 → 方法参数中有一个有关添加视图模型类型的形参,比如vm→ 根据vm的某个属性,比如Name判断在上下文中是否存在,如果不存在就抛EntityNotFoundException异常→ 判断vm所 ...
- 一个使用MVC3+NHibernate “增删改查” 的项目(修正版)
前言: 谈到NHibernate大伙并不陌生,搞Java的更是清楚,Hibernate是一个目前应用的最广泛的开放源代码的对象关系映射框架,它对Java的JDBC(类似于ADO.Net)进行了非常 ...
- 使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序
使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻 ...
- entity framework 新手入门篇(2)-entity framework基本的增删改查
经过前两节的简单描述,终于可以进入entity framework的使用部分了.本节将对entity framework原生的增删改查进行讲解. 承接上面的部分,我们有一个叫做House的数据库,其中 ...
随机推荐
- Java中RuntimeException和Exception的区别
[TOC] 1. 引入RuntimeException public class RuntimeException { public static void main(String[] args) { ...
- python 面向对象之封装与类与对象
封装 一,引子 从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八,小老虎一起装进麻袋,然后把麻袋封上口子.照这种逻辑看,封装='隐藏',这种理解是相当片面的 二,先看如何隐藏 在 ...
- php的格式化数字函数
php格式化数字:位数不足前面加0补足 php格式化数字:位数不足前面加0补足 感谢:http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/12 ...
- LeetCode & Q14-Longest Common Prefix-Easy
String Description: Write a function to find the longest common prefix string amongst an array of st ...
- Python-面向对象(二)-Day7
1.字段 12.方法 43.属性 63.1.属性的基本使用 73.2.实例:对于主机列表 83.3.属性的两种定义方式 94.对于类的成员而言都有两种形式: 144.1.私有成员和公有成员的访问限制不 ...
- ibatis的优缺点及可行性分析
1.优点 简单: 易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现. 实用: 提供了数据映射功能,提供了对底层数据访问的封装(例如ado.net),提供了DAO框架,可以使我 ...
- VS2013 堆栈溢出调查(0xC00000FD: Stack overflow)
在调试一个代码时,执行过程中会出现如下错误(0xC00000FD: Stack overflow). 很明显是堆栈溢出了. 网上很多方法,都是通过修改设置工程配置,把堆栈调大一些,如下图. 但是堆栈到 ...
- tcpdump记录
tcpdump -i eth0 -nn -A -X 'host 192.168.20.82 and port 9080' -i:interface 监听的网卡. -nn:表示以ip和port的方式显示 ...
- 算法 排序lowB三人组 冒泡排序 选择排序 插入排序
参考博客:基于python的七种经典排序算法 [经典排序算法][集锦] 经典排序算法及python实现 首先明确,算法的实质 是 列表排序.具体就是操作的列表,将无序列表变成有序列表! 一 ...
- oracle:批量插入不同方案对比
实时测试的速度: --48466条数据 --1.297 inline view更新法 inline view更新法就是更新一个临时建立的视图 update (select a.join_stateas ...