.NET Core 中的 ORM 框架对比

        在 .NET Core 中选择正确的对象关系映射 (ORM) 工具可能是开发生命周期中的关键决策。所选的 ORM 会影响应用程序的性能、可维护性和可伸缩性。在本文中,我们将深入分析三个突出的 ORM 选择:Entity Framework Core、Dapper 和 NHibernate。

        每个 ORM 都有其优点和缺点,我们将通过实际的代码示例来探索它们。1. 实体框架核心实体框架核心(EF Core)是Microsoft的官方ORM,以其简单性和与其他Microsoft技术的集成而闻名。它支持各种数据库提供程序,并遵循约定优先于配置的方法。让我们深入研究一个详细的例子:模型定义public

        在 .NET Core 中选择正确的对象关系映射 (ORM) 工具可能是开发生命周期中的关键决策。所选的 ORM 会影响应用程序的性能、可维护性和可伸缩性。在本文中,我们将深入分析三个突出的 ORM 选择:Entity Framework Core、Dapper 和 NHibernate。每个 ORM 都有其优点和缺点,我们将通过实际的代码示例来探索它们。

1. EF Core

Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术。

EF Core 可用作对象关系映射程序 (O/RM),这可以实现以下两点:

  • 使 .NET 开发人员能够使用 .NET 对象处理数据库。
  • 无需再像通常那样编写大部分数据访问代码。
  • EF查询使用的是LINQ进行查询

让我们深入研究一个详细的例子:

模型定义

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    public int Rating { get; set; }
    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

数据库上下文

public class BloggingContext : DbContext
{
    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(
            @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True");
    }
}

查询数据

using (var db = new BloggingContext())
{
    var blogs = db.Blogs
        .Where(b => b.Rating > 3)
        .OrderBy(b => b.Url)
        .ToList();
}

保存数据

using (var db = new BloggingContext())
{
    var blog = new Blog { Url = "http://sample.com" };
    db.Blogs.Add(blog);
    db.SaveChanges();
}

EF O/RM 注意事项

虽然 EF Core 善长提取许多编程详细信息,但还是有一些适用于任何 O/RM 的最佳做法,可帮助避免生产应用中的常见陷阱:

  • 若要在高性能生产应用中构建、调试、分析和迁移数据,必须具备基础数据库服务器的中级知识或更高级别的知识。 例如,有关主键和外键、约束、索引、标准化、DML 和 DDL 语句、数据类型、分析等方面的知识。
  • 功能和集成测试:请务必尽可能严密地复制生产环境,以便:
    • 查找仅在使用特定版本的数据库服务器时应用才出现的问题。
    • 在升级 EF Core 和其他依赖项时捕获中断性变更。 例如,添加或升级 ASP.NET Core、OData 或 AutoMapper 等框架。 这些依赖项可能以多种意外方式影响 EF Core。
  • 通过代表性负载进行性能和压力测试。 某些功能的不成熟用法缩放性不佳。 例如,多项集合包含内容、大量使用延迟加载、对未编制索引的列执行条件查询、对存储生成的值进行大规模更新和插入、缺乏并发处理、大型模型、缓存策略不充分。
  • 安全评审:例如,连接字符串和其他机密处理、非部署操作的数据库权限、原始 SQL 的输入验证、敏感数据加密。
  • 确保日志记录和诊断充足且可用。 例如,适当的日志记录配置、查询标记和 Application Insights。
  • 错误恢复。 为常见故障场景(如版本回退、回退服务器、横向扩展和负载平衡、DoS 缓解和数据备份)准备应急计划。
  • 应用程序部署和迁移。 规划如何在部署过程中应用迁移;在应用程序启动时执行此操作可能会导致并发问题,并且对于常规操作,这所需的权限比必要权限更高。 在迁移期间,使用暂存来辅助从错误中恢复。 有关详细信息,请参阅应用迁移。
  • 生成的迁移的详细检查和测试。 将迁移应用于生产数据前,应对其进行全面测试。 若表中包含生产数据,架构的形状和列类型就不能轻易更改。 例如,在 SQL Server 上,对于映射到字符串和十进制属性的列,nvarchar(max) 和 decimal(18, 2) 极少成为最佳类型,但这些是 EF 使用的默认值,因为 EF 不了解你的具体情况。

2.Dapper

        Dapper 主要能够让你练习你的 SQL 技能,按你认为的那样构建查询和命令。它接近于“金属”而非标准的 ORM,免除了解释查询的工作。Dapper 可以通过其 API 为你执行查询以及—假如查询结果的架构与目标类型的属性相匹配—自动实例化对象并向对象填充查询结果。此处还有另一个显著的性能优势: Dapper 能够有效缓存它获悉的映射,从而实现后续查询的极速反序列化。

DapperDesigner 类

public class DapperDesigner
{
  public DapperDesigner() {
    Products = new List<Product>();
    Clients = new List<Client>();
  }
  public int Id { get; set; }
  public string LabelName { get; set; }
  public string Founder { get; set; }
  public Dapperness Dapperness { get; set; }
  public List<Client> Clients { get; set; }
  public List<Product> Products { get; set; }
  public ContactInfo ContactInfo { get; set; }
}

查询代码类 

var designers = sqlConn.Query<DapperDesigner>("select * from DapperDesigners"); 

Dapper 和关系查询 

var sql = @"select * from DapperDesigners D            JOIN Products P            ON P.DapperDesignerId = D.Id"; var designers= conn.Query<DapperDesigner, Product,DapperDesigner> (sql,(designer, product) => { designer.Products.Add(product);                               return designer; });

编码难度加大,执行速度变快 

Dapper 是精确控制 SQL 查询和高性能数据访问至关重要的场景的绝佳选择。它对于读取密集型应用程序特别有用。

Dapper使用查询用的是原始的SQL。

3. NHibernate

NHibernate是Hibernate的C#版,众所周知Hibernate是Java 里ORM的顶梁柱。与EntityFramework不同的地方是,Hibernate以配置文件为主,通过配置文件规范使用,Object/Relation 映射。而NHibernate这继承了这一点,也是以配置文件优先

映射

需要创建一个项目用的配置文件:App.config.

C# 项目中,除了Web类型的项目,每个项目的主配置文件的名称都是App.config,这是一个固定名称。

文件内容如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
</configuration>
在 configuration节点之间添加以下内容:

<configSections>
    <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate"/>
  </configSections>
这段代码的含义是,在config文件中添加一个 hibernate-configuration结点,结点的解析由类:NHibernate.Cfg.ConfigurationSectionHandler,所在包是NHibernate。

在App.config文件configuration结点中添加以下代码:

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
    <session-factory>
        <property name="dialect">NHibernate.Dialect.MsSql2012Dialect</property>
        <property name="connection.connection_string">
            Data Source=.;Initial Catalog=Demo;Integrated Security=True
        </property>
        <property name="hbm2ddl.auto">create-drop</property>
        <mapping assembly="dataprovider" />
    </session-factory>
</hibernate-configuration>
这是固定格式,其中dialect表示使用的数据库类型,connection.connection_string 表示连接字符串。mapping表示映射关系文件所在项目。

获取ISessionFactory

然后获取一个ISessionFactory:

Configuration cfg = new Configuration();
var sessionFactory = cfg.BuildSessionFactory();
当然,如果直接运行代码的话,会在 BuildSessionFactory这里报错。因为没有为SQL Server安装数据访问驱动:

System.Data.SqlClient
将数据访问驱动安装成功后,运行可以获得sessionFactory。

sessionFactory用来创建一个访问数据库的Session

 增删改查

先来个简单的示例类:

public class Cat
{
    public virtual string Id { get; set; }
    public virtual string Name { get; set; }
    public virtual char Sex { get; set; }
    public virtual float Weight { get; set; }
}
NHibernate的映射关系文件:Cat.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="dataprovider" assembly="dataprovider">
  <class name="Cat" table="Cat">

    <!-- A 32 hex character is our surrogate key. It's automatically
            generated by NHibernate with the UUID pattern. -->
    <id name="Id">
      <column name="CatId" sql-type="char(32)" not-null="true"/>
      <generator class="uuid.hex" />
    </id>
    <!-- A cat has to have a name, but it shouldn't be too long. -->
    <property name="Name">
      <column name="Name" length="16" not-null="true" />
    </property>
    <property name="Sex" />
    <property name="Weight" />
  </class>
</hibernate-mapping>
创建完成后,右键选中文件,修改文件生成操作为嵌套的资源


然后编写实例代码:

Configuration cfg = new Configuration().Configure();

using (var sessionFactory = cfg.BuildSessionFactory())
using (var session = sessionFactory.OpenSession())
{
// 通过session操作
    session.Close();
}
新增一个Cat:

var princess = new Cat
{
    Name = "Princess",
    Sex = 'F',
    Weight = 7.4f
};
session.Save(princess);
session.Flush();//推送修改给数据库,不调用的话数据库里将没有数据
查询并修改:

var cats = session.Query<Cat>().ToList();
var cat = cats.First();
cat.Name = "xiao li";
session.Update(cat);
session.Flush();
查询并删除:

var cats = session.Query<Cat>().ToList();
var cat = cats.First();
session.Delete(cat);
session.Flush();

结论

        在 .NET Core 中选择 ORM 涉及评估项目的特定需求和权衡。Entity Framework Core 在简单性和基于约定的开发方面表现出色,Dapper 最适合对性能敏感的方案,而 NHibernate 为复杂的应用程序提供了广泛的功能。根据项目的要求做出明智的决策,你将在 .NET Core 应用程序中实现高效且可维护的数据库交互。

注意:

        三种ORM映射虽然采取的映射方式不同,但是在数据操作中都有一个共同的特征就是建立上下文数据库对象或者缓存工厂,以此来简化数据操作的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/558375.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Antd:在文本框中展示格式化JSON

要想将对象转换为格式化 JSON 展示在文本框中&#xff0c;需要用到 JSON.stringify JSON.stringify 方法接受三个参数&#xff1a; value&#xff1a;必需&#xff0c;一个 JavaScript 值&#xff08;通常为对象或数组&#xff09;要转换为 JSON 字符串。replacer&#xff1a…

商务品牌解决方案企业网站模板 Bootstrap5

目录 一.前言 二.展示 三.下载链接 一.前言 这个网站包含以下内容&#xff1a; 导航栏&#xff1a;主页&#xff08;Home&#xff09;、关于&#xff08;About&#xff09;、服务&#xff08;Services&#xff09;、博客&#xff08;Blog&#xff09;等页面链接。主页部分…

Adipogen—Progranulin (human) ELISA Kit (mAb/mAb)

前颗粒蛋白&#xff08;Progranulin&#xff0c;PGRN&#xff09;是一种富含半胱氨酸的蛋白质&#xff0c;由~ 6kDa大小的颗粒蛋白&#xff08;granulin&#xff0c;GRN&#xff09;组成&#xff0c;具有多功能生物活性&#xff0c;在癌症、炎症、代谢性疾病和神经退行性疾病中…

2024洗地机名牌排行榜:细数最值得买的4大热门款

随着科技的迅速发展&#xff0c;人们的家里纷纷都添置了新的清洁工具——洗地机&#xff0c;它集合了吸、拖、洗于一体&#xff0c;减轻了很多家庭家务的负担&#xff0c;也成为了很多家庭改善清洁体验的新选择。那么市场上的洗地机品牌琳琅满目&#xff0c;我们要如何挑选一款…

教你三招,玩转AI通用大模型ChatGPT

工欲善其事必先利其器&#xff0c;想要高效的用好ChatGPT&#xff0c;首先&#xff0c;让我们从如何与它进行有效的对话开始。要知道&#xff0c;ChatGPT并非简单的问答机器&#xff0c;而是一个可以通过交互学习和适应的智能体。那么&#xff0c;如何让ChatGPT来更好地理解我们…

ruoyi创建子模块

点击项目 -> new -> Module 选择maven模式 构建完成 子项目默认会加入到父项目maven控制在 父项目 pom文件中 dependencyManagement 标签内加入一下代码 新建子模块的名称<!-- 测试--><dependency><groupId>com.safety</groupId><artifact…

vscode+vue开发常用插件整理

前言&#xff1a; vscode新机开发常用插件整理 1、chinese 简体中文配置 2、file-jump 别名跳转&#xff0c;可以把引入的组件&#xff0c;通过ctrl地址名 跳转组件内部 3、Vue Peek&#xff1a;vue项目中的一些配置&#xff0c;安装后&#xff0c;能实现 ctrl组件名 跳转…

JavaEE进阶:基础知识

JavaEE&#xff1a;Java企业开发 Web网站的工作流程 ⽬前用户对PC端应⽤的开发结构模式主要分为C/S和B/S结构. CS即Client/Server&#xff08;客户机/服务器&#xff09;结构. 常⻅的C/S架构的应⽤⽐如QQ&#xff0c;CCTALK&#xff0c;各种⽹络游戏 等等&#xff0c;⼀般需…

【创建型模式】工厂方法模式

一、简单工厂模式 1.1 简单工厂模式概述 简单工厂模式又叫做静态工厂方法模式。 目的&#xff1a;定义一个用于创建对象的接口。实质&#xff1a;由一个工厂类根据传入的参数&#xff0c;动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。 简单工厂模式…

MYSQL之增删改查(上)

前言&#xff1a; 以下是MySQL最基本的增删改查语句&#xff0c;很多IT工作者都必须要会的命令&#xff0c;也 是IT行业面试最常考的知识点&#xff0c;由于是入门级基础命令&#xff0c;所有所有操作都建立在单表 上&#xff0c;未涉及多表操作。 1、“增”——添加数据 1.1…

【简单介绍下R-Tree】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

228 基于matlab的神经网络人脸识别

基于matlab的神经网络人脸识别。 人脸识别以视网膜、 虹膜、 指纹等生物特征的识别作为生物标识符。生物特征识别不很容易伪造、 放错位置。新型脸识别使用的方法 RobustPCA 和径向基函数网络。程序已调通&#xff0c;可直接运行。 228 人脸识别 生物特征识 神经网络 - 小红书 …

【NTN 卫星通信】NTN的信关站应该建在哪些地方

1 概述 3GPP的卫星通信讨论了透传星和再生星两种方式。透传星方式&#xff0c;卫星主要是做为中继存在&#xff0c;基本上不做通信协议的处理。再生星方式&#xff0c;gNodeB的主要功能在卫星上&#xff0c;完成通信协议的主要内容。无论是透传星还是再生星&#xff0c;都需要通…

校园小情书微信小程序源码/社区小程序前后端开源/校园表白墙交友小程序

校园小情书前端代码&#xff0c;好玩的表白墙、树洞、校园论坛&#xff0c;可独立部署&#xff0c;也可以使用我部署的后台服务&#xff0c;毕业设计的好项目。 搭建教程&#xff1a; 一、注册管理后台 1、登录小情书站点进行注册&#xff1a;https://你的域名 2、注册成功…

【JavaEE多线程】线程中断 interrupt()

系列文章目录 &#x1f308;座右铭&#x1f308;&#xff1a;人的一生这么长、你凭什么用短短的几年去衡量自己的一生&#xff01; &#x1f495;个人主页:清灵白羽 漾情天殇_计算机底层原理,深度解析C,自顶向下看Java-CSDN博客 ❤️相关文章❤️&#xff1a;清灵白羽 漾情天…

动态酷黑主页源码

效果图 PC端 &#xff08;移动端不能访问&#xff09; 部分代码 index.html <!DOCTYPE html> <html lang"zh-CN"> <head> <meta http-equiv"X-UA-Compatible" content"IEedge,chrome1"> <meta charset"ut…

java算法day58 | 单调栈part01 ● 739. 每日温度 ● 496.下一个更大元素 I

739. 每日温度 思路&#xff1a; 这道题用暴力求解法会超时。 那我们就要想如何只遍历一遍就能求解出每个位置的下一个更大值在哪呢。 主要的思想就是空间换时间。定义一个单调栈&#xff0c;每次遇到比栈顶元素小的或相等的&#xff0c;直接入栈&#xff0c;遇到比栈顶元素大的…

电学启蒙积木电子方案

东莞市酷得智能科技有限公司是一家集芯片贸易和电子方案定制开发的研发型公司&#xff0c;其中电子积木方案是酷得经营多年的其中一条比较成熟的研发线。电学积木玩具不仅仅是一种娱乐工具&#xff0c;更是一种教育工具&#xff0c;能够在孩子们的成长过程中发挥多方面的积极作…

微信小程序开发五(与springboot整合)

首先在微信开发者工具中开启不校验合法域名&#xff0c;这个才能本地访问 实现一个小功能&#xff1a; 展示数据信息&#xff0c;每条数据的颜色不一样 后端&#xff1a;springbootmybatisplusmysql 依赖&#xff1a; <dependency><groupId>com.baomidou</grou…

代码学习记录45---单调栈

随想录日记part45 t i m e &#xff1a; time&#xff1a; time&#xff1a; 2024.04.17 主要内容&#xff1a;今天开始要学习单调栈的相关知识了&#xff0c;今天的内容主要涉及&#xff1a;每日温度 &#xff1b;下一个更大元素 I 739. 每日温度 496.下一个更大元素 I Topic…
最新文章