From 4bf278943b514984221bce4a714a24a0c9d3b2fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=A8=9C?= <2977047384@qq.com> Date: Fri, 13 Dec 2024 08:06:46 +0800 Subject: [PATCH 1/2] biji --- ...56\345\272\223\350\277\236\346\216\245.md" | 390 ++++++++++++++++++ .../20241211-linq\346\237\245\350\257\242.md" | 85 ++++ 2 files changed, 475 insertions(+) create mode 100644 "\346\235\216\345\250\234/20241209-mvc\346\225\260\346\215\256\345\272\223\350\277\236\346\216\245.md" create mode 100644 "\346\235\216\345\250\234/20241211-linq\346\237\245\350\257\242.md" diff --git "a/\346\235\216\345\250\234/20241209-mvc\346\225\260\346\215\256\345\272\223\350\277\236\346\216\245.md" "b/\346\235\216\345\250\234/20241209-mvc\346\225\260\346\215\256\345\272\223\350\277\236\346\216\245.md" new file mode 100644 index 0000000..5447961 --- /dev/null +++ "b/\346\235\216\345\250\234/20241209-mvc\346\225\260\346\215\256\345\272\223\350\277\236\346\216\245.md" @@ -0,0 +1,390 @@ +# ASP.NET MVC 中数据库连接笔记 + +## 1. 概述 + +在ASP.NET MVC应用程序中,数据库连接是实现数据持久化的关键部分。通常,使用Entity Framework(EF)作为ORM(对象关系映射)工具来简化数据库操作。EF提供了强大的功能来创建、读取、更新和删除(CRUD)数据库中的数据。 + +## 2. 数据库连接步骤概述 + +1. **创建数据库和表**: 使用SQL Server或其他数据库管理系统创建数据库和所需的表。 +2. **创建MVC项目**: 在Visual Studio中创建一个新的ASP.NET MVC项目。 +3. **安装Entity Framework**: 通过NuGet包管理器安装EF。 +4. **配置数据库连接字符串**: 在`Web.config`文件中配置数据库连接字符串。 +5. **创建数据模型**: 使用EF的Code First或Database First方法创建数据模型。 +6. **实现数据访问**: 在控制器中实现数据访问逻辑。 +7. **展示数据**: 在视图中展示从数据库获取的数据。 + +## 3. 详细步骤和代码示例 + +### 3.1 创建数据库和表 + +假设我们使用SQL Server,并创建一个名为`LinqPracticeDB`的数据库,包含一个`Customers`表。 + +```sql +CREATE DATABASE LinqPracticeDB; + +USE LinqPracticeDB; + +CREATE TABLE Customers ( + CustomerID INT IDENTITY(1,1) PRIMARY KEY, + Name NVARCHAR(100) NOT NULL, + Email NVARCHAR(100) NOT NULL, + Phone NVARCHAR(20) +); +``` + +### 3.2 创建MVC项目 + +在Visual Studio中创建一个新的ASP.NET MVC项目,选择“空”模板并添加MVC文件夹和核心引用。 + +### 3.3 安装Entity Framework + +使用NuGet包管理器安装Entity Framework。在“包管理器控制台”中运行以下命令: + +```powershell +Install-Package EntityFramework +``` + +### 3.4 配置数据库连接字符串 + +在`Web.config`文件中添加数据库连接字符串。例如: + +```xml + + + +``` + +### 3.5 创建数据模型 + +使用Code First方法创建数据模型。创建一个`Models`文件夹,并在其中创建`Customer.cs`: + +```csharp +using System.ComponentModel.DataAnnotations; + +namespace LinqPractice.Models +{ + public class Customer + { + [Key] + public int CustomerID { get; set; } + + [Required] + [StringLength(100)] + public string Name { get; set; } + + [Required] + [StringLength(100)] + public string Email { get; set; } + + [StringLength(20)] + public string Phone { get; set; } + } +} +``` + +创建数据库上下文`LinqPracticeDBContext.cs`: + +```csharp +using System.Data.Entity; + +namespace LinqPractice.Models +{ + public class LinqPracticeDBContext : DbContext + { + public LinqPracticeDBContext() : base("LinqPracticeDBContext") + { + } + + public DbSet Customers { get; set; } + } +} +``` + +### 3.6 实现数据访问 + +创建一个控制器`CustomersController.cs`来处理客户数据的CRUD操作。 + +```csharp +using System.Linq; +using System.Web.Mvc; +using LinqPractice.Models; + +namespace LinqPractice.Controllers +{ + public class CustomersController : Controller + { + private LinqPracticeDBContext db = new LinqPracticeDBContext(); + + // GET: Customers + public ActionResult Index() + { + var customers = db.Customers.ToList(); + return View(customers); + } + + // GET: Customers/Details/5 + public ActionResult Details(int id) + { + var customer = db.Customers.Find(id); + if (customer == null) + { + return HttpNotFound(); + } + return View(customer); + } + + // GET: Customers/Create + public ActionResult Create() + { + return View(); + } + + // POST: Customers/Create + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult Create(Customer customer) + { + if (ModelState.IsValid) + { + db.Customers.Add(customer); + db.SaveChanges(); + return RedirectToAction("Index"); + } + return View(customer); + } + + // GET: Customers/Edit/5 + public ActionResult Edit(int id) + { + var customer = db.Customers.Find(id); + if (customer == null) + { + return HttpNotFound(); + } + return View(customer); + } + + // POST: Customers/Edit/5 + [HttpPost] + [ValidateAntiForgeryToken] + public ActionResult Edit(Customer customer) + { + if (ModelState.IsValid) + { + db.Entry(customer).State = EntityState.Modified; + db.SaveChanges(); + return RedirectToAction("Index"); + } + return View(customer); + } + + // GET: Customers/Delete/5 + public ActionResult Delete(int id) + { + var customer = db.Customers.Find(id); + if (customer == null) + { + return HttpNotFound(); + } + return View(customer); + } + + // POST: Customers/Delete/5 + [HttpPost, ActionName("Delete")] + [ValidateAntiForgeryToken] + public ActionResult DeleteConfirmed(int id) + { + var customer = db.Customers.Find(id); + db.Customers.Remove(customer); + db.SaveChanges(); + return RedirectToAction("Index"); + } + + protected override void Dispose(bool disposing) + { + if (disposing) + { + db.Dispose(); + } + base.Dispose(disposing); + } + } +} +``` + +### 3.7 创建视图 + +在`Views/Customers`文件夹中创建以下视图: + +- **Index.cshtml**: 显示客户列表。 + +```html +@model IEnumerable + + + + + 客户列表 + + +

客户列表

+ + + + + + + + + + + + @foreach (var customer in Model) + { + + + + + + + + } + +
ID姓名电子邮件电话操作
@customer.CustomerID@customer.Name@customer.Email@customer.Phone + @Html.ActionLink("详情", "Details", new { id = customer.CustomerID }) | + @Html.ActionLink("编辑", "Edit", new { id = customer.CustomerID }) | + @Html.ActionLink("删除", "Delete", new { id = customer.CustomerID }) +
+

+ @Html.ActionLink("添加新客户", "Create") +

+ + +``` + +- **Create.cshtml**: 添加新客户。 + +```html +@model LinqPractice.Models.Customer + + + + + 添加新客户 + + +

添加新客户

+ @using (Html.BeginForm()) + { + @Html.AntiForgeryToken() +
+ @Html.LabelFor(m => m.Name) + @Html.TextBoxFor(m => m.Name) +
+
+ @Html.LabelFor(m => m.Email) + @Html.TextBoxFor(m => m.Email) +
+
+ @Html.LabelFor(m => m.Phone) + @Html.TextBoxFor(m => m.Phone) +
+ + } + + +``` + +- **Edit.cshtml**: 编辑客户信息。 + +```html +@model LinqPractice.Models.Customer + + + + + 编辑客户 + + +

编辑客户

+ @using (Html.BeginForm()) + { + @Html.AntiForgeryToken() + @Html.HiddenFor(m => m.CustomerID) +
+ @Html.LabelFor(m => m.Name) + @Html.TextBoxFor(m => m.Name) +
+
+ @Html.LabelFor(m => m.Email) + @Html.TextBoxFor(m => m.Email) +
+
+ @Html.LabelFor(m => m.Phone) + @Html.TextBoxFor(m => m.Phone) +
+ + } + + +``` + +- **Details.cshtml**: 显示客户详情。 + +```html +@model LinqPractice.Models.Customer + + + + + 客户详情 + + +

客户详情

+
+ ID: @Model.CustomerID +
+
+ 姓名: @Model.Name +
+
+ 电子邮件: @Model.Email +
+
+ 电话: @Model.Phone +
+

+ @Html.ActionLink("返回", "Index") +

+ + +``` + +- **Delete.cshtml**: 删除客户。 + +```html +@model LinqPractice.Models.Customer + + + + + 删除客户 + + +

删除客户

+

确定要删除客户 "@Model.Name" 吗?

+ @using (Html.BeginForm()) + { + @Html.AntiForgeryToken() + @Html.HiddenFor(m => m.CustomerID) + + } +

+ @Html.ActionLink("返回", "Index") +

+ + +``` diff --git "a/\346\235\216\345\250\234/20241211-linq\346\237\245\350\257\242.md" "b/\346\235\216\345\250\234/20241211-linq\346\237\245\350\257\242.md" new file mode 100644 index 0000000..cd4a6a5 --- /dev/null +++ "b/\346\235\216\345\250\234/20241211-linq\346\237\245\350\257\242.md" @@ -0,0 +1,85 @@ +# MVC中LINQ查询 + +## 1. LINQ简介 + +LINQ(Language Integrated Query,语言集成查询)是微软为.NET Framework提供的一种查询技术,允许开发者在C#等语言中直接使用类似SQL的语法进行数据查询和操作。LINQ支持多种数据源,包括集合、数据库、XML等,并提供统一的查询语法。 + +## 2. LINQ查询的基本语法 + +### 2.1 查询表达式语法 + +LINQ查询表达式语法类似于SQL,常见结构如下: + +```csharp +var query = from item in dataSource + where condition + orderby item.Property ascending/descending + select item; +``` + +- **from**: 指定数据源和范围变量。 +- **where**: 过滤数据,返回满足条件的元素。 +- **orderby**: 对结果进行排序,可以指定升序(ascending)或降序(descending)。 +- **select**: 定义查询结果的形状或类型。 + +### 2.2 方法语法 + +方法语法使用扩展方法和Lambda表达式,常见方法包括: + +- **Where**: 过滤数据。 +- **Select**: 投影数据。 +- **OrderBy**: 排序数据。 +- **GroupBy**: 分组数据。 + +示例: + +```csharp +var query = dataSource.Where(item => item.Property > 10) + .OrderBy(item => item.Property) + .Select(item => item.Property); +``` + +## 3. LINQ查询操作符 + +### 3.1 常用操作符 + +- **Where**: 用于筛选数据。 +- **Select**: 用于选择和转换数据。 +- **OrderBy**: 用于排序数据。 +- **GroupBy**: 用于分组数据。 +- **Join**: 用于连接多个数据源。 + +### 3.2 聚合操作符 + +- **Sum**: 计算总和。 +- **Average**: 计算平均值。 +- **Count**: 计算元素数量。 +- **Max** 和 **Min**: 查找最大值和最小值。 + +## 4. LINQ查询的执行 + +### 4.1 延迟执行 + +LINQ查询默认采用延迟执行(Lazy Evaluation),即查询在定义时不立即执行,而是在迭代结果时才执行。这有助于提高性能,尤其是在处理大数据集时。 + +### 4.2 立即执行 + +可以使用诸如 `ToList()`, `ToArray()`, `Count()` 等方法来强制立即执行查询。这些方法会遍历查询结果并生成一个新的集合。 + +## 5. LINQ在MVC中的应用 + +在ASP.NET MVC中,LINQ常用于数据访问层(如Entity Framework)进行数据库操作。以下是一个简单的示例: + +```csharp +public ActionResult GetCustomers(string city) +{ + using (var db = new SampleDataContext()) + { + var customers = from c in db.Customers + where c.City == city + select c; + return View(customers.ToList()); + } +} +``` + -- Gitee From 5a3f96dd2518916292549e534d7dc8dc4078e911 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=A8=9C?= <2977047384@qq.com> Date: Fri, 13 Dec 2024 11:06:17 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E7=AC=94=E8=AE=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../20241211-linq\346\237\245\350\257\242.md" | 26 ++- ...51\345\261\225\346\226\271\346\263\225.md" | 148 ++++++++++++++++++ 2 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 "\346\235\216\345\250\234/20241213-Linq\346\237\245\350\257\242\346\211\251\345\261\225\346\226\271\346\263\225.md" diff --git "a/\346\235\216\345\250\234/20241211-linq\346\237\245\350\257\242.md" "b/\346\235\216\345\250\234/20241211-linq\346\237\245\350\257\242.md" index cd4a6a5..4cc1f80 100644 --- "a/\346\235\216\345\250\234/20241211-linq\346\237\245\350\257\242.md" +++ "b/\346\235\216\345\250\234/20241211-linq\346\237\245\350\257\242.md" @@ -82,4 +82,28 @@ public ActionResult GetCustomers(string city) } } ``` - +# 高级练习 +25. 查询并使用Zip合并 合并两个数组,并创建一个包含元素对的新数组。 +```cs +int[] numbers1 = { 1, 2, 3 }; +int[] numbers2 = { 4, 5, 6 }; +var list = numbers1.Zip(numbers2, (x, y) => x + " " + y); +``` +26. 查询并使用Range生成 生成一个包含1到10的整数数组。 +```cs +var list = Enumerable.Range(1, 10); +``` +27. 查询并使用Repeat重复 重复一个元素多次,创建一个新数组。 +```cs +var list = Enumerable.Repeat("我是一个元素", 10); +``` +28. 查询并使用Take限制数量 从数组中取出前5个元素。 +```cs +int[] numbers = { 1, 2, 3, 4, 5, 6,18,23,64,7,18,2,3 }; +var list = numbers.Take(5); +``` +29. 查询并使用Skip跳过元素 跳过数组中的前3个元素,然后取出剩余的元素。 +```cs +int[] numbers = { 1, 2, 3, 4, 5, 6,18,23,64,7,18,2,3 }; +var list = numbers.Skip(3); +``` diff --git "a/\346\235\216\345\250\234/20241213-Linq\346\237\245\350\257\242\346\211\251\345\261\225\346\226\271\346\263\225.md" "b/\346\235\216\345\250\234/20241213-Linq\346\237\245\350\257\242\346\211\251\345\261\225\346\226\271\346\263\225.md" new file mode 100644 index 0000000..adaf9d9 --- /dev/null +++ "b/\346\235\216\345\250\234/20241213-Linq\346\237\245\350\257\242\346\211\251\345\261\225\346\226\271\346\263\225.md" @@ -0,0 +1,148 @@ +# LINQ 扩展方法知识笔记 +LINQ 中常用的扩展方法,并扩展相关知识: + +- Zip +- Range +- Repeat +- Take +- Skip + +## 一、LINQ 扩展方法概述 + +LINQ(语言集成查询)提供了一组扩展方法,可以对集合(如数组、列表等)进行各种查询和操作。这些方法主要定义在 `System.Linq` 命名空间下,扩展了 `IEnumerable` 接口。 + +## 二、常用 LINQ 扩展方法详解 + +### 1. Zip + +- **功能**: 将两个序列按元素一一对应进行合并,生成一个新的序列。 +- **使用场景**: 需要将两个相关联的集合合并成一个集合,例如将学生姓名和成绩对应起来。 +- **语法**: + ```csharp + IEnumerable Zip( + IEnumerable first, + IEnumerable second, + Func resultSelector) + ``` +- **示例**: + ```csharp + int[] numbers1 = { 1, 2, 3 }; + int[] numbers2 = { 4, 5, 6 }; + var zipped = numbers1.Zip(numbers2, (x, y) => x + " " + y); // { "1 4", "2 5", "3 6" } + ``` +- **注意事项**: + - 如果两个序列长度不一致,Zip 会以较短的序列为准,忽略多余的元素。 + - 性能开销较小,适用于大多数场景。 + +### 2. Range + +- **功能**: 生成一个指定范围内的整数序列。 +- **使用场景**: 需要生成连续整数序列,例如生成索引、编号等。 +- **语法**: + ```csharp + IEnumerable Range(int start, int count) + ``` + - `start`: 起始值。 + - `count`: 生成的元素个数。 +- **示例**: + ```csharp + var numbers = Enumerable.Range(1, 10); // { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 } + ``` +- **注意事项**: + - `start` 和 `count` 的组合可能会导致溢出,需注意范围。 + - 性能开销较小,适用于需要生成整数序列的场景。 + +#### 3. Repeat + +- **功能**: 生成一个重复元素的序列。 +- **使用场景**: 需要生成包含重复元素的集合,例如初始化默认值、填充数据等。 +- **语法**: + ```csharp + IEnumerable Repeat(TResult element, int count) + ``` + - `element`: 要重复的元素。 + - `count`: 重复的次数。 +- **示例**: + ```csharp + var repeated = Enumerable.Repeat("重复元素", 5); // { "重复元素", "重复元素", "重复元素", "重复元素", "重复元素" } + ``` +- **注意事项**: + - `count` 为负数时会抛出异常。 + - 适用于需要重复生成相同元素的场景,性能开销较小。 + +#### 4. Take + +- **功能**: 从序列的开头获取指定数量的元素。 +- **使用场景**: 需要限制查询结果的数量,例如分页查询、获取前 N 个结果等。 +- **语法**: + ```csharp + IEnumerable Take(this IEnumerable source, int count) + ``` +- **示例**: + ```csharp + int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + var firstFive = numbers.Take(5); // { 1, 2, 3, 4, 5 } + ``` +- **注意事项**: + - 如果 `count` 大于序列长度,则返回整个序列。 + - Take 不延迟执行,会立即执行查询。 + +#### 5. Skip + +- **功能**: 跳过序列开头的指定数量的元素,返回剩余的元素。 +- **使用场景**: 需要跳过前 N 个元素,例如分页查询、跳过前 N 个结果等。 +- **语法**: + ```csharp + IEnumerable Skip(this IEnumerable source, int count) + ``` +- **示例**: + ```csharp + int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; + var lastFive = numbers.Skip(5); // { 6, 7, 8, 9, 10 } + ``` +- **注意事项**: + - 如果 `count` 大于序列长度,则返回一个空序列。 + - Skip 同样不延迟执行,会立即执行查询。 + +### 三、扩展知识 + +#### 1. 延迟执行(Deferred Execution) + +- **概念**: LINQ 查询在定义时不会立即执行,而是在迭代查询结果时才执行。 +- **优点**: + - 提高性能,避免不必要的计算。 + - 支持链式调用,可以组合多个查询操作。 +- **示例**: + ```csharp + var query = numbers.Where(n => n > 5); + // 查询尚未执行 + + foreach(var num in query) + { + // 查询在此处执行 + } + ``` + +#### 2. 立即执行(Immediate Execution) + +- **概念**: LINQ 查询在定义时立即执行,并生成结果集。 +- **使用场景**: 需要立即获取查询结果,例如需要多次使用查询结果时。 +- **方法**: + - 使用 `ToList()`, `ToArray()`, `Count()`, `First()`, 等方法。 +- **示例**: + ```csharp + var list = numbers.Where(n => n > 5).ToList(); + // 查询立即执行,结果存储在 list 中 + ``` + +#### 3. 组合使用 LINQ 方法 + +- LINQ 方法可以链式调用,组合使用来实现复杂的查询逻辑。 +- **示例**: + ```csharp + var result = numbers.Where(n => n > 5) + .OrderBy(n => n) + .Take(3) + .Skip(1); + // 先筛选大于5的元素,再排序,再取前3个,再跳过1个 + ``` -- Gitee