Entity Framework使用DBContext实现增删改查

2023-12-08 0 958

有一段时间没有更新博客了,赶上今天外面下雨,而且没人约球,打算把最近对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 – 1) * pageSize).Take(pageSize).ToList();
}
}

总结

本文对最新版本的Entity Framework进行增删改查操作给出了详尽的解释,并且给出了数据库和领域模型代码分开设计的完整解决方案,同时介绍了手动数据库表和领域模型映射,数据库事务实现,分页查询等常用功能,希望对大家有所帮助。

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对悠久资源网的支持。如果你想了解更多相关内容请查看下面相关链接

您可能感兴趣的文章:

  • C#在EntityFramework中实现事务回滚
  • Entity Framework代码优先Code First入门
  • Entity Framework映射TPH、TPT、TPC与继承类
  • EntityFramework主从表的增删改
  • Entity Framework配置关系
  • EntityFramework主从表数据加载方式
  • Entity Framework代码优先(Code First)模式
  • Entity Framework使用ObjectContext类
  • Entity Framework模型优先与实体对象查询

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 ASP.NET Entity Framework使用DBContext实现增删改查 https://www.u-9.cn/biancheng/aspnet/128897.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务