C#MVC4基础(四)(数据建模(二)(通过代码建立数据库)(主从表查询(贪婪加载,延迟加载)))

本文深入讲解CodeFirst模式,包括如何通过编写代码自动创建模型和数据库,实现类与数据库表之间的映射,以及一对多关系的处理。探讨了数据库生成、模型约定、数据上下文类的创建、延迟加载与贪婪加载等概念。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Code First模式

代码优先(编写代码来自动创建模型和数据库)

使用类创建模型

  1. 创建ASP.NET MVC应用程序,并选择“基本”模板
  2. 在Models文件夹上右键选择新建类,并命名为ks类
    public class ks
    {
        public int id { get; set; }
        public string Name { get; set; }
        public string PassWord { get; set; }
        public virtual ICollection<sl> sl { get; set; }
    }
  1. 继续新建类并命名为sl
public class sl
    {
        public int id { get; set; }
        public string Phone { get; set; }
        public virtual ks ks { get; set; }
    }
  1. 创建数据上下文类,表示数据库的一个会话,以便查询和绑定对象
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity; //记得引用

namespace Demo4.Models
{
    public class mlgm : DbContext  //引用DbContext父类
    {
        public DbSet<ks> ks { get; set; }
        public DbSet<sl> sl { get; set; }
        
    }
}

PS:带virtual的属性,称为“导航属性”。表示启用EF框架的延迟加载功能。延迟加载意味着,尝试访问这些属性内容时,将自动从数据库加载。

生成数据库:

  1. 打开Web.config,查找数据库连接字符串“DefaultConnection”,将其修改为:
    <add name="mlgm" providerName="System.Data.SqlClient" connectionString="Data Source=.;Initial Catalog=sy;Integrated Security=SSPI;" />

PS:name属性对应数据库上下文类类名,connectionString中Initial Catalog对应数据库名,Integrated Security=SSPI表示启用Window登录验证
2. 新建控制器和视图,在控制器中的Index方法中,编写以下代码

 public ActionResult Index()
        {
            using (mlgm m = new mlgm())
            {
                ks k = new ks();
                k.Name = "美丽副矛";
                k.PassWord = "刷卡单";
                m.ks.Add(k);
                m.SaveChanges();
            }
            return View();
        }
  1. 启动程序,打开SQLServer,就可以看到自动创建的sy数据库了其中ks表中还有一条新增数据

模型的默认约定

  1. 表和字段名的约定
    Code First约定表名使用EF框架的复数化服务,即使用英语语法的类名复数形式来命名表名。

关闭代码如下:
数据库上下文类中引用(using System.Data.Entity.ModelConfiguration.Conventions;)并输入

protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        } 

默认情况下,每个表都使用dbo框架创建。
实体类属性映射的列与类中字段的名称一致命名。

  1. 关于主键的约定
    Code First默认约定将命名为id或“类名+id”的属性视为表的主键。
    如果这些属性还是整型类型,Code First会自动将他们配置为数据库的标识字段
    PS:SQLserver2012不区分大小写,所以id或者ID什么的都一样

  2. 字符串属性的约定
    默认数据类型nvarchar(max),同时允许空值

  3. 一对多关系的约定
    sl类中有一个ks类型的属性,ks类中有一个List属性。Code First将此视为一对多关系,自动给sl生成一个外键约束的属性。

更新数据库

数据上下文类中添加类的无参构造函数

//手动设置数据库初始化(先删再加)
        public mlgm()
        {
            Database.SetInitializer(new DropCreateDatabaseIfModelChanges<mlgm>());
        }

主从表查询

  1. 延迟加载
    只在需要的时候加载数据,当对象使用时,再去数据库中加载。当实体对象读取数据时,关联的数据并不会被获取。只有访问关联属性时,被导航属性关联的数据才会被自动读取。这可能导致多次查询被发送到数据库,一次是读取实体本身,对于关联的每个实体也需要分别读取。
  2. 贪婪加载
    一次性组织好数据,并加载到内存。当实体加载时,向关联的数据也一同被加载。典型运用于一次连接查询后返回所有需要的相关数据的情况。
  3. 显示加载
    这种方式类似于延迟加载,除非需要在代码中显示获取数据。在访问导航属性时,不会出现自动加载。手动加载关联的数据,通过访问对象状态管理器来获取实体,调用Collection.Load方法获取集合,或调用持有单个实体的属性的Reference.Load方法

优劣:

贪婪加载:
1、减少数据访问的延迟,在一次数据库的访问中返回所有的数据。
2、一次性读取所有相关的数据,可能导致部分数据实际无需用到,从而导致读取数据的速度变慢,效率变低
延迟加载:
1、只在需要读取关联数据的时候才进行加载
2、可能因为数据访问的延迟而降低性能,因为循环中,每一条数据都会访问一次数据库,导致数据库的压力加大

EF默认支持延迟加载,有两种方法可以关闭延迟加载: 1. 对于特定的导航属性,在定义属性时取消virtual
2. 对于所有的导航属性在数据上下文类的构造函数中设置LazyLoadingEnabled为false

Configuration.LazyLoadingEnabled = false;

代码块:

m是数据上下文类对象,ks是主表,sl是从表

//延迟加载(只加载主表数据)
var user = from u in m.ks where u.ksID == 1 select u;
//贪婪加载(可以和linq查询共用)(在一次数据库的访问中返回所有的数据)(加载主从表数据)
var user = from u in m.ks.Include("sl") where u.ksID == 1 select u;
//遍历
foreach (ks l in user)
                {
                    foreach (sl o in l.sl)  //EF查询导航属性的时候,只要查询到内存没有相应的数据,每次会再度向去查询一下数据库
                    {
 
                    }
                }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值