EF框架基础应用入门

一、介绍

  • 什么是Entity Framework(EF)框架

Entity Framework(EF)框架是微软提供的一种对象关系映射(ORM)框架,用于简化与数据库的交互和数据访问操作。它允许开发人员使用面向对象的方式来操作数据库,而无需编写大量的SQL语句。

EF框架的主要作用是将数据库中的表和表之间的关系映射到.NET平台上的对象模型中,使开发人员可以使用面向对象的编程技术进行数据库操作。它提供了一组强大的API,包括通过LINQ进行数据查询、插入、更新和删除等常见的数据操作。

  • EF框架的作用和优势
  1. 简化数据访问: EF框架提供了简单易用的API,使开发人员能够以面向对象的方式进行数据操作,而不必关心底层数据库操作的细节。
  2. 提高开发效率: 使用EF框架可以减少手动编写SQL语句的工作量,节省开发时间,提高开发效率。
  3. 跨数据库支持: EF框架支持多种数据库,包括SQL Server、MySQL、Oracle等,使开发人员能够轻松切换和适应不同的数据库环境。
  4. 面向对象的数据操作: EF框架将数据库中的表和关系转换为对象模型,使开发人员可以使用面向对象的编程技术,如继承、多态等,更方便地进行数据操作。
  5. 可维护性和可重用性: 使用EF框架可以提高代码的可读性、可维护性和可重用性,使软件开发更加灵活和可靠。
  • EF框架在软件开发中的应用场景
  1. 企业级应用开发: EF框架适用于开发大型企业级应用程序,其中数据访问是一个关键组成部分。它可以简化数据操作,并提供强大的查询功能,有助于提高开发效率和应用性能。
  2. Web应用开发: EF框架可以与ASP.NET和ASP.NET Core等Web开发框架集成,用于处理数据库操作。它可以帮助开发人员快速构建可靠的Web应用程序,并提供高效的数据访问。
  3. 移动应用开发: EF框架可以与移动应用开发框架(如Xamarin)结合使用,用于处理本地数据库的访问。它可以简化移动应用的数据管理,并提供一致的数据访问接口。
  4. 服务端开发: EF框架可以与ASP.NET Web API或WCF等服务端开发技术结合使用,用于处理数据的持久化和访问。它可以帮助开发人员快速构建可靠的服务端应用程序,并提供强大的数据操作功能。

二、EF6框架基础

1. 数据模型和实体类

定义实体模型类,表示数据库中的表和表之间的关系。

public class Product
{
    
    
    public int Id {
    
     get; set; }
    public string Name {
    
     get; set; }
    public decimal Price {
    
     get; set; }
}

public class Order
{
    
    
    public int Id {
    
     get; set; }
    public DateTime OrderDate {
    
     get; set; }
    public List<Product> Products {
    
     get; set; }
}

2. 数据库上下文(DbContext)介绍

创建派生自DbContext的类,用于与数据库进行交互。

public class MyDbContext : DbContext
{
    
    
    public DbSet<Product> Products {
    
     get; set; }
    public DbSet<Order> Orders {
    
     get; set; }
}

3. 配置数据模型与数据库表的映射关系

两种方式Fluent API和数据注解

Fluent API

重写DbContext的OnModelCreating方法在其方法内进行映射

public class MyDbContext : DbContext
{
    
    
    public DbSet<Product> Products {
    
     get; set; }
    public DbSet<Order> Orders {
    
     get; set; }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
    
    

                modelBuilder.Entity<Product>().ToTable("Product").HasKey(p => p.Id);
                modelBuilder.Entity<Order>().ToTable("Order").HasKey(o => o.Id);
         }
        
}

数据注解

[Table("Product")] // 指定数据库表的名称
public class Product
{
    
    
	
    [Column(TypeName = "bigint")]//映射到数据库中对应的字段数据类型
    [Key]//标识为主键 
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]//设置主键生成策略
    public int Id {
    
     get; set; }
    [Required]//标识字段为非空字段
    [Column(TypeName = "varchar")]
    [StringLength(50)]//设置数据类型的大小    
    public string Name {
    
     get; set; }
    public decimal Price {
    
     get; set; }
}

public class Order
{
    
    
    public int Id {
    
     get; set; }
    public DateTime OrderDate {
    
     get; set; }
    public List<Product> Products {
    
     get; set; }
}

在这里插入图片描述

4. 数据库迁移(Migration)概述

数据库迁移是一种管理数据库架构变更的方式,通过代码来自动更新数据库结构。

如果您在使用 Entity Framework 过程中遇到了 “No migrations configuration type was found in the assembly” 错误,这通常意味着缺少迁移配置。

在 Entity Framework 中,每个项目都需要一个迁移配置类用于管理数据库迁移。迁移配置类是从 DbMigrationsConfiguration 基类派生而来的。这个类负责指定数据库提供程序、连接字符串以及其他与迁移相关的配置。

如果您使用的是 Entity Framework 6,请按照以下步骤执行 “Enable-Migrations” 命令添加迁移配置:

  1. 打开 Visual Studio,并打开您的项目。
  2. 打开“包管理器控制台”窗口。可以在 Visual Studio 菜单栏中选择 “工具” > “NuGet 包管理器” > “程序包管理器控制台”。
  3. 在“程序包管理器控制台”窗口中,确保 “默认项目” 下拉菜单中选择了您的项目。
  4. 在 “程序包管理器控制台” 窗口中输入以下命令:
Enable-Migrations

这将创建一个名为 Configuration.cs 的迁移配置类,并添加到您的项目中。

a. 创建初始迁移

使用EF命令行工具创建初始迁移及数据库。

  1. 添加迁移:
Add-Migration InitialCreate

该命令将在代码中生成一个新的迁移文件,在该文件中定义了将应用于数据库的更改。

  1. 更新数据库:
Update-Database

该命令将应用迁移文件中定义的更改,并将这些更改应用到目标数据库中。

b. 更新迁移

在模型类或配置类发生变化后,生成并应用新的迁移脚本。

  1. 添加迁移:
Add-Migration AddNewColumn

该命令将在代码中生成一个新的迁移文件,并根据需要定义要应用于数据库的更改,例如添加新的列。

  1. 更新数据库:
Update-Database

该命令将应用迁移文件中定义的更改,并将这些更改应用到目标数据库中。

执行这些命令最后都会生成一个类
在这里插入图片描述

三、基本数据操作

1. 查询数据

a. 基本查询语法

使用LINQ查询语法从数据库中检索数据。

using (var context = new MyDbContext())
{
    
    
    var products = context.Products.ToList();
    // 执行查询操作
}

b. 条件查询和排序

根据条件查询数据,并进行排序操作。

using (var context = new MyDbContext())
{
    
    
    var products = context.Products
        .Where(p => p.Price > 10)
        .OrderBy(p => p.Name)
        .ToList();
    // 根据条件进行查询和排序
}

c. 关联查询

在查询中使用Include方法进行关联查询。

using (var context = new MyDbContext())
{
    
    
    var orders = context.Orders
        .Include(o => o.Products)
        .ToList();
    // 进行关联查询
}

2. 插入数据

a. 添加单个实体

向数据库中插入单个实体。

using (var context = new MyDbContext())
{
    
    
    var product = new Product {
    
     Name = "Product1", Price = 20 };
    context.Products.Add(product);
    context.SaveChanges();
    // 添加单个实体到数据库
}

b. 批量添加实体

使用AddRange方法将多个实体添加到数据库。

using (var context = new MyDbContext())
{
    
    
    var products = new List<Product>
    {
    
    
        new Product {
    
     Name = "Product1", Price = 20 },
        new Product {
    
     Name = "Product2", Price = 30 }
    };
    context.Products.AddRange(products);
    context.SaveChanges();
    // 批量添加实体到数据库
}

3. 更新数据

a. 修改现有实体

修改数据库中现有的实体数据。

using (var context = new MyDbContext())
{
    
    
    var product = context.Products.Find(1);
    if (product != null)
    {
    
    
        product.Name = "NewName";
        context.SaveChanges();
        // 修改现有实体数据
    }
}

b. 批量更新实体

通过查询条件批量更新数据库中的实体数据。

using (var context = new MyDbContext())
{
    
    
    var products = context.Products.Where(p => p.Price > 10);
    foreach (var product in products)
    {
    
    
        product.Price += 5;
    }
    context.SaveChanges();
    // 批量更新实体数据
}

4. 删除数据

a. 删除单个实体

从数据库中删除单个实体。

using (var context = new MyDbContext())
{
    
    
    var product = context.Products.Find(1);
    if (product != null)
    {
    
    
        context.Products.Remove(product);
        context.SaveChanges();
        // 删除单个实体
    }
}

b. 批量删除实体

通过查询条件批量删除数据库中的实体。

using (var context = new MyDbContext())
{
    
    
    var products = context.Products.Where(p => p.Price < 10);
    context.Products.RemoveRange(products);
    context.SaveChanges();
    // 批量删除实体
}

四、性能优化

延迟加载和预加载是提高性能的两种常用策略。

延迟加载(Lazy Loading)是指当需要访问导航属性时,才加载相关的数据。这样可以避免不必要的数据加载,减少了查询的开销。例如,在使用 EF6 进行查询时,可以通过禁用延迟加载来减少查询所涉及的数据量:

context.Configuration.LazyLoadingEnabled = false;

预加载(Eager Loading)是指在查询时一次性加载所有相关数据,以减少后续的查询操作。可以使用 Include 方法或 Include 字符串参数来预加载相关的导航属性。下面是一个示例:

var orders = context.Orders.Include(o => o.Customer).ToList();

查询优化技巧包括使用合适的查询方法和索引来提高查询性能。例如,使用 Where 条件来限制结果集的大小,使用 Select 投影出所需的列,以及使用索引来加速查询操作。

缓存机制是通过将数据存储在内存中,减少对数据库的访问次数,从而提高性能。可以使用内存缓存(如 MemoryCache)或分布式缓存(如 Redis)来实现缓存机制。

批量处理数据是指通过使用批量操作来一次性处理多个数据项,而不是逐个进行操作。例如,在 EF6 中可以使用 AddRange 方法来一次性插入多条数据。这样可以减少数据库连接和事务的开销,提高插入、更新和删除的性能。

下面是一个结合代码的示例,展示如何使用延迟加载、预加载、查询优化和批量处理数据来提高性能:

// 延迟加载
var customer = context.Customers.FirstOrDefault();
var orders = customer.Orders.ToList(); // 当访问导航属性时,相关的订单数据才会被加载

// 预加载
var orders = context.Orders.Include(o => o.Customer).ToList(); // 一次性加载所有订单及其关联的顾客数据

// 查询优化
var smallOrders = context.Orders.Where(o => o.Amount < 100).ToList(); // 仅查询金额小于 100 的订单数据

// 缓存机制
var cachedData = memoryCache.Get("CachedData");
if (cachedData == null)
{
    
    
    cachedData = GetDataFromDatabase();
    memoryCache.Set("CachedData", cachedData, TimeSpan.FromMinutes(10));
}

// 批量处理数据
var newCustomers = GetNewCustomers();
context.Customers.AddRange(newCustomers); // 一次性插入多个新顾客数据
context.SaveChanges();

五、错误处理和日志记录

1.异常处理和日志记录

异常处理和日志记录是保证应用程序稳定性和可维护性的重要组成部分。

异常处理可以通过捕获并处理可能出现的异常情况来避免应用程序崩溃或产生不可预料的结果。在代码中使用 try-catch 块来捕获异常,并根据需要进行相应的处理或恢复操作。以下是一个示例:

try
{
    
    
    // 执行可能出现异常的代码
    // ...
}
catch (Exception ex)
{
    
    
    // 处理异常,例如记录日志、发送警报、回滚事务等
    LogException(ex);
    // 进行适当的错误处理
}

在处理异常时,可以根据具体的异常类型进行不同的处理逻辑。例如,可以使用多个 catch 块来捕获特定的异常类型并执行相应的处理代码。

日志记录工具的选择与使用可以根据需求和技术栈进行选择。常见的日志记录工具包括 log4net、NLog、Serilog 等。选择合适的工具后,可以配置日志级别(如 Debug、Info、Warning、Error 等)和输出方式(如控制台、文件、数据库等)。下面是一个使用 log4net 的示例:

// 配置log4net
log4net.Config.XmlConfigurator.Configure(new FileInfo("log4net.config"));

// 记录日志
private static readonly ILog log = LogManager.GetLogger(typeof(Program));

// 使用示例
log.Debug("Debug message");
log.Info("Info message");
log.Warn("Warning message");
log.Error("Error message", exception);

通过日志记录工具,可以记录应用程序运行过程中的关键信息、异常信息以及其他有助于排查问题的数据。日志的输出可以用于开发调试、故障排除和性能分析等场景。

综上所述,异常处理和日志记录是构建健壮应用程序的重要环节。合理地处理异常并记录日志可以提高应用程序的可靠性和可维护性。如果还有任何问题,请随时提问。

2. EF框架的日志记录配置

在Entity Framework框架中,可以通过配置来记录日志以便调试和性能优化。下面是一些常见的操作来配置EF框架的日志记录:

  1. 配置日志记录器: 首先,需要配置一个日志记录器来处理EF框架的日志消息。可以使用第三方的日志库,如NLog、Serilog,或使用内置的日志功能。

  2. 配置DbContext: 在应用程序的DbContext类中,可以通过重写OnConfiguring方法来配置日志记录。在该方法中,可以指定要使用的日志记录器,并设置日志级别。

例子如下(使用Microsoft.Extensions.Logging):

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    
    
    // 配置日志记录器
    ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
    {
    
    
        builder.AddConsole(); // 添加控制台输出作为日志记录器
        // 可以添加其他日志记录器,如AddFile等
    });

    // 设置DbContext的日志记录器
    optionsBuilder.UseLoggerFactory(loggerFactory)
                  .EnableSensitiveDataLogging(); // 启用敏感数据日志记录

    // 其他配置...
}
  1. 设置日志级别: 在配置日志记录器时,可以设置日志的级别以过滤不需要的日志消息。常见的级别有InformationWarningError等。

  2. 输出SQL查询语句: 如果需要记录EF框架生成的SQL查询语句,可以启用敏感数据日志记录(EnableSensitiveDataLogging),这将在日志中显示生成的SQL语句和参数值。但请注意,由于敏感数据可能包含敏感信息,如密码等,因此要谨慎处理和存储这些日志。

  3. 处理日志消息: 在配置日志记录器时,可以添加处理程序来对日志消息进行处理。例如,可以将日志消息写入日志文件、发送到远程服务器或进行其他自定义操作。具体的处理方式取决于所使用的日志库和需求。

配置EF框架的日志记录可以帮助我们更好地了解EF框架在运行时生成的SQL查询语句、执行时间等信息,有助于调试和性能优化。根据实际需求,可以按照上述步骤来配置和自定义EF框架的日志记录。

猜你喜欢

转载自blog.csdn.net/pengjun_ge/article/details/132719177