共计 4617 个字符,预计需要花费 12 分钟才能阅读完成。
导读 | 这篇文章介绍了 Entity Framework 使用 DBContext 实现增删改查的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下 |
有一段时间没有更新博客了,赶上今天外面下雨,而且没人约球,打算把最近对 Entity Framework DBContext 使用的心得梳理一下,早些时候在网上简单查过,对于最新版本的 EF 并没有类似的知识梳理类文章,希望对大家有所帮助。
我为什么讨厌 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 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:
DB Context:
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;
using Model;
namespace DataAccess
{public class TTableConfiguration : EntityTypeConfiguration
{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 Destinations {get; set;}
public DbSet Lodgings {get; set;}
public DbSet TTables {get; set;}
}
}
比如本文的 TTable 表是在 TTT Schema 下面的,而其他表示设计在 DBO 下面,最方便的方式是使用 fluent API, 具体代码如请参见 TTableConfiguration Class 和 OnModelCreating() 方法,可配置的粒度非常细,比如可以配置领域模型和数据库的哪个 Schema 的哪张表的哪一列对应,本文是将 TTable 类的数据库表配置为了 TTT Schema 下的 TTable 表,
public class TTableConfiguration : EntityTypeConfiguration
{public TTableConfiguration()
{this.ToTable("TTable", "TTT");
}
}
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 dest = context.Destinations.Where(a => a.DestinationId == destId);
return dest.Single();}
}
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());
}
}
}
}
public static List QueryPaging(int pageIndex, int pageSize, Expression> whereLambda, Expression> orderBy)
{using (var context = new BreakAwayContext(ConfigurationManager.ConnectionStrings["BAContext"].ConnectionString))
{return context.Destinations.Where(whereLambda).OrderBy(orderBy).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();}
}
本文对最新版本的 Entity Framework 进行增删改查操作给出了详尽的解释,并且给出了数据库和领域模型代码分开设计的完整解决方案,同时介绍了手动数据库表和领域模型映射,数据库事务实现,分页查询等常用功能,希望对大家有所帮助。