欢迎光临
我们一直在努力

EF框架三种开发模式 + 原生SQL + 导航属性 + LINQ全套复习笔记

一、EF框架三种开发模式(必考区分)

1. DB First 数据库优先(最常用)

先有数据库、数据表,VS根据数据库自动生成实体类、上下文。

特点:适合传统项目、已有数据库、快速开发、不用手写实体。

2. Code First 代码优先

先手写实体类、上下文,通过迁移命令自动生成/更新数据库表结构。

特点:适合新项目、敏捷开发、版本迭代、字段新增修改。

3. Model First 模型优先

拖拽模型设计器生成实体关系,再生成数据库,目前基本淘汰。


二、DBFirst 数据库优先(EF封装CRUD + 导航属性)

1. 核心概念:导航属性(必背)

导航属性:实体类中用于描述表与表外键关联的属性。

作用:无需手写联表SQL,直接通过对象点属性获取关联表数据。

示例:public AddressInfo AddressInfo { get; set; }

2. 全局上下文对象

// 全局数据库上下文
BankSystemEntities context = new BankSystemEntities();

3. 导航属性联表查询

private void button4_Click(object sender, EventArgs e)
{
// 1. 查询主表单个对象
UserInfo u1 = context.UserInfo.Find(1);

// 2. 通过导航属性直接获取外键关联的子表数据(无需Join)
foreach (var a in u1.AddressInfo.ToList())
{
MessageBox.Show(a.City);
}
}

4. EF 添加数据

private void button1_Click(object sender, EventArgs e)
{
// 1. 实例化实体
UserInfo u1 = new UserInfo()
{
Account = "123",
Password = "123",
CreateUserId = 1,
LastUpdateTime = DateTime.Now,
CreateTime = DateTime.Now,
Status = 1
};
// 2. 上下文临时添加
context.UserInfo.Add(u1);
// 3. 提交到数据库(核心)
int row = context.SaveChanges();

if (row > 0)
{
MessageBox.Show("添加成功");
BindView();
}
else
{
MessageBox.Show("添加失败");
}
}

5. EF 删除数据

private void button2_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count > 0)
{
int id = Convert.ToInt32(dataGridView1.SelectedRows[0].Cells["UserId"].Value);
UserInfo u1 = context.UserInfo.Find(id);

// 删除方式一:Remove移除对象
context.UserInfo.Remove(u1);

// 删除方式二:修改实体状态为删除
// context.Entry(u1).State = System.Data.Entity.EntityState.Deleted;

int row = context.SaveChanges();
if (row > 0)
{
MessageBox.Show("删除成功");
BindView();
}
}
}

6. EF 修改数据

private void button3_Click(object sender, EventArgs e)
{
if (dataGridView1.SelectedRows.Count > 0)
{
int id = Convert.ToInt32(dataGridView1.SelectedRows[0].Cells["UserId"].Value);
UserInfo u1 = context.UserInfo.Single(m => m.UserId == id);

// 赋值更新
u1.Password = "888888";
u1.Account = "787777";

// 自动追踪属性变更,无需手动标记状态
int row = context.SaveChanges();
if (row > 0)
{
BindView();
}
}
}

7. 数据绑定方法

private void BindView()
{
dataGridView1.DataSource = context.UserInfo.ToList();
}

private void Form1_Load(object sender, EventArgs e)
{
BindView();
// 隐藏导航属性列(避免界面乱码)
if (dataGridView1.Columns["AddressInfo"] != null)
{
dataGridView1.Columns["AddressInfo"].Visible = false;
}
}


三、EF 执行原生SQL语句(参数化防注入)

适用场景:复杂SQL、存储过程、EF语法难以实现的查询

1. 原生SQL查询数据

private void BindView()
{
string sql = "select * from UserInfo";
// 执行查询SQL,返回实体集合
List<UserInfo> list = context.Database.SqlQuery<UserInfo>(sql).ToList();
dataGridView1.DataSource = list;
}

2. 原生SQL新增(参数化)

private void button1_Click(object sender, EventArgs e)
{
string sql = "insert into UserInfo(Account,Password,CreateUserId,CreateTime,LastUpdateTime,Status) " +
"VALUES(@Account,@Password,@CreateUserId,@CreateTime,@LastUpdateTime,@Status)";

// 防止SQL注入
SqlParameter[] paras = new SqlParameter[]
{
new SqlParameter("@Account","123456"),
new SqlParameter("@Password","123456"),
new SqlParameter("@CreateUserId",1),
new SqlParameter("@CreateTime",DateTime.Now),
new SqlParameter("@LastUpdateTime",DateTime.Now),
new SqlParameter("@Status",0)
};

int row = context.Database.ExecuteSqlCommand(sql, paras);
if (row > 0)
{
MessageBox.Show("插入成功");
BindView();
}
}

3. 原生SQL修改、删除

// 修改
private void button2_Click(object sender, EventArgs e)
{
string sql = "update UserInfo set Account = @Account,Password =@Password where UserId=@UserId";
SqlParameter[] paras = new SqlParameter[]
{
new SqlParameter("@Account","123456"),
new SqlParameter("@Password","123456888"),
new SqlParameter("@UserId",5006),
};
int row = context.Database.ExecuteSqlCommand(sql, paras);
}

// 删除
private void button3_Click(object sender, EventArgs e)
{
string sql = "delete from UserInfo where UserId = @UserId";
SqlParameter[] paras = new SqlParameter[]
{
new SqlParameter("@UserId",5005),
};
int row = context.Database.ExecuteSqlCommand(sql, paras);
}

4. 原生SQL多表查询替代导航属性

private void button4_Click(object sender, EventArgs e)
{
// 1. 查询主表
string sql = "select * from UserInfo where UserId=@UserId";
SqlParameter para = new SqlParameter("@UserId", 1);
UserInfo info = context.Database.SqlQuery<UserInfo>(sql, para).FirstOrDefault();

// 2. 根据主表ID查询子表
string sql1 = "select * from AddressInfo where CreateUserId=@a";
SqlParameter para1 = new SqlParameter("@a", info.UserId);
List<AddressInfo> list = context.Database.SqlQuery<AddressInfo>(sql1, para1).ToList();

foreach (var item in list)
{
MessageBox.Show(item.City);
}
}


四、EF CodeFirst 代码优先完整流程

1. 使用步骤(必背考试步骤)

  • NuGet 安装EF:Install-Package EntityFramework -Version 6.5.2

  • 配置数据库连接字符串

  • 手写实体类

  • 创建上下文类,继承 DbContext

  • 执行迁移命令生成/更新数据库

  • 2. 迁移命令(必考)

    Enable-Migrations // 首次开启迁移
    Add-Migration init // 添加迁移记录(init=初始化)
    Update-Database // 更新到数据库

    // 新增字段迭代
    Add-Migration AddNewColumn
    Update-Database

    3. CodeFirst 新增数据示例

    namespace _02ef代码优先
    {
    public partial class Form1 : Form
    {
    UserInfoModel u1 = new UserInfoModel();

    public void BindView()
    {
    dataGridView1.DataSource = u1.UserInfos.ToList();
    }

    private void button1_Click(object sender, EventArgs e)
    {
    UserInfo u2 = new UserInfo()
    {
    Account = "123456",
    Password = "Password",
    Status = 1,
    Status1 = 0
    };
    u1.UserInfos.Add(u2);
    int row = u1.SaveChanges();
    if (row > 0)
    {
    MessageBox.Show("添加成功");
    BindView();
    }
    }
    }
    }


    五、LINQ 全套基础语法(查询语法 + 方法语法)

    1. 两种查询模式

    • 查询语法(from):可读性高、类似SQL

    • 方法语法(Lambda):简洁、企业常用

    2. 查询语法基础

    int[] ints = new int[] { 1, 2, 3, 4, 5, 6 };

    // 条件、排序、投影
    IEnumerable<string> query = from s in ints
    where s > 1 && s < 4
    orderby s descending
    select s + "分";

    foreach (var s in query)
    {
    MessageBox.Show(s);
    }

    3. 字符串模糊查询

    string[] names = { "xibanya", "agenting", "faguo" };
    var query1 = from s in names
    where s.StartsWith("a")
    select s;

    4. 嵌套集合查询

    Student[] students = new Student[]
    {
    new Student() { Id =1,Name="罗志祥",Favobrite = new string[]{"聊天","跳舞","rap"} },
    new Student() { Id =2,Name="吴亦凡",Favobrite = new string[]{"唱歌","跳舞","rap"} },
    new Student() { Id =3,Name="蔡徐坤",Favobrite = new string[]{"唱歌","跳舞","rap","打篮球"} },
    };

    // 嵌套from查询子集合
    var query3 = from s in students
    where s.Name == "蔡徐坤"
    from s2 in s.Favobrite
    where s2.EndsWith("球")
    select s2;

    5. Lambda 方法语法(Where/OrderBy/Select)

    int[] ints = { 1, 2, 3, 4 };
    // 筛选 + 排序 + 投影
    var query1 = ints.Where(v => v > 2)
    .OrderByDescending(v => v)
    .Select(v => v * 2);


    六、LINQ + EF 分页 + 多条件筛选(大题终极模板)

    namespace _04linq和代码优先示例
    {
    public partial class Form1 : Form
    {
    public MyEntities my = new MyEntities();
    public int pageIndex = 1;
    public int pageSize = 2;

    // 绑定数据(筛选 + 分页)
    private void BindView()
    {
    using (MyEntities my = new MyEntities())
    {
    IQueryable<StudentInfo> query = getFilterQuery(my);
    // 分页核心代码
    var list = query.Skip((pageIndex – 1) * pageSize)
    .Take(pageSize)
    .ToList();
    dataGridView1.DataSource = list;
    }
    }

    // 通用多条件筛选
    public IQueryable<StudentInfo> getFilterQuery(MyEntities m)
    {
    IQueryable<StudentInfo> query = m.StudentInfos;

    // 模糊查询
    if (!string.IsNullOrEmpty(textBox1.Text))
    {
    query = query.Where(v => v.Name.Contains(textBox1.Text));
    }
    // 下拉框状态筛选
    if (comboBox1.SelectedIndex > 0)
    {
    int a = Convert.ToInt32(comboBox1.Text);
    query = query.Where(v => v.Status == a);
    }

    // 排序
    query = query.OrderByDescending(v => v.Id);
    return query;
    }

    // 上一页、下一页
    private void button1_Click(object sender, EventArgs e) { pageIndex++; BindView(); }
    private void button3_Click(object sender, EventArgs e)
    {
    if (pageIndex > 1) pageIndex–;
    BindView();
    }
    }
    }

    七、期末必背核心考点总结

  • 导航属性:替代联表SQL,快速获取外键关联数据,DBFirst自动生成

  • EF两种操作方式:1. EF语法CRUD 2. 原生SQL参数化CRUD(防注入)

  • CodeFirst三步:安装EF、写实体+上下文、迁移命令生成数据库

  • LINQ两种写法:查询语法(from)、Lambda方法语法

  • 分页核心函数:Skip()跳过条数、Take()读取条数

  • IQueryable/IEnumerable区别:IQueryable延迟查询、性能高;IEnumerable本地内存筛选

  • 赞(0)
    未经允许不得转载:171主机测评 » EF框架三种开发模式 + 原生SQL + 导航属性 + LINQ全套复习笔记
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址