C# 13 和 .NET 9 全知道 :10 使用实体框架核心处理数据 (4)
bigegpt 2025-01-07 10:58 3 浏览
过滤包含的实体
EF Core 5 引入了过滤包含,这意味着您可以在 Include 方法调用中指定一个 lambda 表达式,以过滤返回结果中的实体:
- 在 Program.Queries.cs 中,定义一个 FilteredIncludes 方法并添加语句以执行这些任务,如以下代码所示:创建一个将管理数据库的 Northwind 类的实例。提示用户输入库存中的最小单位值。创建一个查询,查找库存中具有该最小数量单位的产品的类别。遍历类别和产品,输出每个产品的名称和库存单位:
private static void FilteredIncludes()
{
using NorthwindDb db = new();
SectionTitle("Products with a minimum number of units in stock");
string? input;
int stock;
do
{
Write("Enter a minimum for units in stock: ");
input = ReadLine();
} while (!int.TryParse(input, out stock));
IQueryable<Category>? categories = db.Categories?
.Include(c => c.Products.Where(p => p.Stock >= stock));
if (categories is null || !categories.Any())
{
Fail("No categories found.");
return;
}
foreach (Category c in categories)
{
WriteLine(
"{0} has {1} products with a minimum {2} units in stock.",
arg0: c.CategoryName, arg1: c.Products.Count, arg2: stock);
foreach(Product p in c.Products)
{
WriteLine(#34; {p.ProductName} has {p.Stock} units in stock.");
}
}
}
在 Program.cs 中,调用 FilteredIncludes 方法,如下代码所示:
FilteredIncludes();
运行代码,输入库存中的最小值,例如 100 ,并查看结果,如下所示的部分输出:
Enter a minimum for units in stock: 100
Beverages has 2 products with a minimum of 100 units in stock.
Sasquatch Ale has 111 units in stock.
Rh?nbr?u Klosterbier has 125 units in stock.
Condiments has 2 products with a minimum of 100 units in stock.
Grandma's Boysenberry Spread has 120 units in stock.
Sirop d'érable has 113 units in stock.
Confections has 0 products with a minimum of 100 units in stock.
Dairy Products has 1 products with a minimum of 100 units in stock.
Geitost has 112 units in stock.
Grains/Cereals has 1 products with a minimum of 100 units in stock.
Gustaf's Kn?ckebr?d has 104 units in stock.
Meat/Poultry has 1 products with a minimum of 100 units in stock.
Paté chinois has 115 units in stock.
Produce has 0 products with a minimum of 100 units in stock.
Seafood has 3 products with a minimum of 100 units in stock.
Inlagd Sill has 112 units in stock.
Boston Crab Meat has 123 units in stock.
R?d Kaviar has 101 units in stock.
Windows 控制台中的 Unicode 字符:在 Windows 10 秋季创意者更新之前的 Windows 版本中,微软提供的控制台存在一个限制。默认情况下,控制台无法显示 Unicode 字符,例如,名称为 Rh?nbr?u 的字符。
如果您遇到此问题,则可以通过在运行应用程序之前在提示符下输入以下命令,暂时将控制台中的代码页(也称为字符集)更改为 Unicode UTF-8:
chcp 65001
过滤和排序产品
让我们探索一个更复杂的查询,它将过滤和排序数据:
- 在 Program.Queries.cs 中,定义一个 QueryingProducts 方法,并添加语句以执行以下操作,如以下代码所示:创建一个将管理数据库的 Northwind 类的实例。提示用户输入产品价格。使用 LINQ 创建一个查询,查找价格高于指定价格的产品。循环遍历结果,输出 ID、名称、成本(以美元格式)和库存单位数量:
private static void QueryingProducts()
{
using NorthwindDb db = new();
SectionTitle("Products that cost more than a price, highest at top");
string? input;
decimal price;
do
{
Write("Enter a product price: ");
input = ReadLine();
} while (!decimal.TryParse(input, out price));
IQueryable<Product>? products = db.Products?
.Where(product => product.Cost > price)
.OrderByDescending(product => product.Cost);
if (products is null || !products.Any())
{
Fail("No products found.");
return;
}
foreach (Product p in products)
{
WriteLine(
"{0}: {1} costs {2:$#,##0.00} and has {3} in stock.",
p.ProductId, p.ProductName, p.Cost, p.Stock);
}
}
- 在 Program.cs 中,调用 QueryingProducts 方法。
- 运行代码,当提示输入产品价格时输入 50 ,查看结果,并注意按成本降序排列,如以下部分输出所示:
Enter a product price: 50
38: C?te de Blaye costs $263.50 and has 17 in stock.
29: Thüringer Rostbratwurst costs $123.79 and has 0 in stock.
9: Mishi Kobe Niku costs $97.00 and has 29 in stock.
20: Sir Rodney's Marmalade costs $81.00 and has 40 in stock.
18: Carnarvon Tigers costs $62.50 and has 42 in stock.
59: Raclette Courdavault costs $55.00 and has 79 in stock.
51: Manjimup Dried Apples costs $53.00 and has 20 in stock.
运行代码,当提示输入产品价格时输入 500 ,并查看结果,如下输出所示:
Fail > No products found.
获取生成的 SQL
您可能会想知道我们编写的 C# 查询生成的 SQL 语句写得有多好。EF Core 5 引入了一种快速简便的方法来查看生成的 SQL:
- 在 QueryingProducts 方法中,在使用 foreach 语句枚举查询之前,添加一条语句以输出生成的 SQL,如以下代码所示:
// Calling ToQueryString does not execute against the database.
// LINQ to Entities just converts the LINQ query to an SQL statement.
Info(#34;ToQueryString: {products.ToQueryString()}");
警告! ToQueryString 方法只能在实现 IQueryable 的对象上工作。这意味着如果您使用延迟方法编写 LINQ 查询,例如 Where 、 GroupBy 、 Select 、 OrderBy 、 Join 、 Take 、 Skip 、 Reverse 等,那么 ToQueryString 可以在您运行查询之前显示 SQL。但是返回非 IQueryable 值并立即执行查询的方法,例如单个标量结果如 Count() 或 First() ,不支持 ToQueryString 。
- 运行代码,输入库存中的最小值,例如 95 ,并查看结果,如下所示的部分输出:
Enter a minimum for units in stock: 95
Connection: Data Source=C:\cs13net9\Chapter10\WorkingWithEFCore\bin\Debug\net9.0\Northwind.db
Info > ToQueryString: .param set @__stock_0 95
SELECT "c"."CategoryId", "c"."CategoryName", "c"."Description", "t"."ProductId", "t"."CategoryId", "t"."UnitPrice", "t"."Discontinued", "t"."ProductName", "t"."UnitsInStock"
FROM "Categories" AS "c"
LEFT JOIN (
SELECT "p"."ProductId", "p"."CategoryId", "p"."UnitPrice", "p"."Discontinued", "p"."ProductName", "p"."UnitsInStock"
FROM "Products" AS "p"
WHERE "p"."UnitsInStock" >= @__stock_0
) AS "t" ON "c"."CategoryId" = "t"."CategoryId"
ORDER BY "c"."CategoryId"
Beverages has 2 products with a minimum of 95 units in stock.
Sasquatch Ale has 111 units in stock.
Rh?nbr?u Klosterbier has 125 units in stock.
...
请注意,名为 @__stock_0 的 SQL 参数已设置为最低库存值 95 。
如果您使用的是 SQL Server,生成的 SQL 将会略有不同。例如,它在对象名称周围使用方括号而不是双引号,如下所示的输出:
Info > ToQueryString: DECLARE @__stock_0 smallint = CAST(95 AS smallint);
SELECT [c].[CategoryId], [c].[CategoryName], [c].[Description], [t].[ProductId], [t].[CategoryId], [t].[UnitPrice], [t].[Discontinued], [t].[ProductName], [t].[UnitsInStock]
FROM [Categories] AS [c]
LEFT JOIN (
SELECT [p].[ProductId], [p].[CategoryId], [p].[UnitPrice], [p].[Discontinued], [p].[ProductName], [p].[UnitsInStock]
FROM [Products] AS [p]
WHERE [p].[UnitsInStock] >= @__stock_0
) AS [t] ON [c].[CategoryId] = [t].[CategoryId]
ORDER BY [c].[CategoryId]
记录 EF Core
要监控 EF Core 与数据库之间的交互,我们可以启用日志记录。日志记录可以输出到控制台、 Debug 或 Trace ,或文件。为 EF Core 启用日志记录会显示实际执行的所有 SQL 命令。 ToQueryString 不会对数据库执行。
良好实践:默认情况下,EF Core 日志记录将排除任何敏感数据。您可以通过调用 EnableSensitiveDataLogging 方法来包含这些数据,特别是在开发期间。您应该在部署到生产环境之前禁用它。您还可以调用 EnableDetailedErrors 。
让我们看看这个实际应用的例子:
- 在 NorthwindDb.cs 中,在 OnConfiguring 方法的底部,添加语句以记录到控制台,并在我们编译调试配置时包含敏感数据,例如发送到数据库的命令的参数值,如以下代码所示:
optionsBuilder.LogTo(WriteLine) // This is the Console method.
#if DEBUG
.EnableSensitiveDataLogging() // Include SQL parameters.
.EnableDetailedErrors()
#endif
;
- LogTo 需要一个 Action<string> 委托。EF Core 将调用此委托,为每条日志消息传递一个 string 值。因此,传递 Console 类的 WriteLine 方法告诉记录器将每个方法写入控制台。
- 请注意,当解决方案配置为调试时,对 EnableSensitiveDataLogging 和 EnableDetailedErrors 方法的调用会包含在编译中,但如果您将解决方案配置更改为发布,这些方法调用会变为灰色,以表示它们未被编译,如图 10.6 所示:
运行代码并查看日志消息,日志消息显示在以下部分输出中:
warn: 7/16/2023 14:03:40.255 CoreEventId.SensitiveDataLoggingEnabledWarning[10400] (Microsoft.EntityFrameworkCore.Infrastructure)
Sensitive data logging is enabled. Log entries and exception messages may include sensitive application data; this mode should only be enabled during development.
...
dbug: 05/03/2023 12:36:11.702 RelationalEventId.ConnectionOpening[20000] (Microsoft.EntityFrameworkCore.Database.Connection)
Opening connection to database 'main' on server 'C:\cs13net9\Chapter10\WorkingWithEFCore\bin\Debug\net9.0\Northwind.db'.
dbug: 05/03/2023 12:36:11.718 RelationalEventId.ConnectionOpened[20001] (Microsoft.EntityFrameworkCore.Database.Connection)
Opened connection to database 'main' on server 'C:\cs13net9\Chapter10\WorkingWithEFCore\bin\Debug\net9.0\Northwind.db'.
dbug: 05/03/2023 12:36:11.721 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT "c"."CategoryId", "c"."CategoryName", "c"."Description", "p"."ProductId", "p"."CategoryId", "p"."UnitPrice", "p"."Discontinued", "p"."ProductName", "p"."UnitsInStock"
FROM "Categories" AS "c"
LEFT JOIN "Products" AS "p" ON "c"."CategoryId" = "p"."CategoryId"
ORDER BY "c"."CategoryId"
...
您的日志可能与上述显示的内容有所不同,这取决于您选择的数据库提供程序和代码编辑器,以及未来对 EF Core 的改进。目前,请注意,不同的事件,如打开连接或执行命令,具有不同的事件 ID,如下所示:
- 20000 RelationalEventId.ConnectionOpening : 包含数据库文件路径
- 20001 RelationalEventId.ConnectionOpened : 包含数据库文件路径
- 20100 RelationalEventId.CommandExecuting : 包含 SQL 语句
按提供商特定值过滤日志
事件 ID 值及其含义将特定于 EF Core 提供程序。如果我们想知道 LINQ 查询是如何被转换为 SQL 语句并执行的,那么要输出的事件 ID 具有 Id 值为 20100 :
- 在 NorthwindDb.cs 的顶部,导入用于处理 EF Core 诊断的命名空间,如下代码所示:
// To use RelationalEventId.
using Microsoft.EntityFrameworkCore.Diagnostics;
将 LogTo 方法调用修改为仅输出 20100 的 Id 事件,如以下代码中突出显示的内容所示:
optionsBuilder.LogTo(WriteLine, // This is the Console method.
new[] { RelationalEventId.CommandExecuting })
#if DEBUG
.EnableSensitiveDataLogging()
.EnableDetailedErrors()
#endif
;
运行代码并注意以下记录的 SQL 语句,如下输出所示,已为节省空间进行了编辑:
dbug: 05/03/2022 12:48:43.153 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT "c"."CategoryId", "c"."CategoryName", "c"."Description", "p"."ProductId", "p"."CategoryId", "p"."UnitPrice", "p"."Discontinued", "p"."ProductName", "p"."UnitsInStock"
FROM "Categories" AS "c"
LEFT JOIN "Products" AS "p" ON "c"."CategoryId" = "p"."CategoryId"
ORDER BY "c"."CategoryId"
Beverages has 12 products.
Condiments has 12 products.
Confections has 13 products.
Dairy Products has 10 products.
Grains/Cereals has 7 products.
Meat/Poultry has 6 products.
Produce has 5 products.
Seafood has 12 products.
使用查询标签进行日志记录
在记录 LINQ 查询时,在复杂场景中关联日志消息可能会很棘手。EF Core 2.2 引入了查询标签功能,通过允许您向日志添加 SQL 注释来提供帮助。
您可以使用 TagWith 方法对 LINQ 查询进行注释,如以下代码所示:
IQueryable<Product>? products = db.Products?
.TagWith("Products filtered by price and sorted.")
.Where(product => product.Cost > price)
.OrderByDescending(product => product.Cost);
这将向日志添加一个 SQL 注释,如下所示的输出:
-- Products filtered by price and sorted.
获取单个实体
有两个 LINQ 方法可以获取单个实体: First 和 Single 。在使用 EF Core 数据库提供程序时,理解它们之间的区别非常重要。让我们看一个例子:
- 在 Program.Queries.cs 中,定义一个 GettingOneProduct 方法,并添加语句以执行以下操作,如以下代码所示:创建一个将管理数据库的 Northwind 类的实例。提示用户输入产品 ID。使用 First 和 Single 方法为具有该产品 ID 的产品创建查询。为每个查询编写一个 SQL 语句到控制台:
private static void GettingOneProduct()
{
using NorthwindDb db = new();
SectionTitle("Getting a single product");
string? input;
int id;
do
{
Write("Enter a product ID: ");
input = ReadLine();
} while (!int.TryParse(input, out id));
// This query is not deferred because the First method does not return IEnumerable or IQueryable.
// The LINQ query is immediately converted to SQL and executed to fetch the first product.
Product? product = db.Products?
.First(product => product.ProductId == id);
Info(#34;First: {product?.ProductName}");
if (product is null) Fail("No product found using First.");
product = db.Products?
.Single(product => product.ProductId == id);
Info(#34;Single: {product?.ProductName}");
if (product is null) Fail("No product found using Single.");
}
获取单个实体的 LINQ 方法( First 、 FirstOrDefault 、 Single 、 SingleOrDefault 、 ElementAt 和 ElementAtOrDefault )或返回单个标量值或实体的聚合方法( Count 、 Sum 、 Max 、 Min 、 Average 、 All 、 Any 等)不是延迟执行的。当使用 LINQ to Entities 提供程序时,任何以调用这些方法之一结尾的 LINQ 查询会立即转换为 SQL 语句并在数据库中执行。
- 在 Program.cs 中,调用 GettingOneProduct 方法。
- 运行代码,当提示输入产品 ID 时输入 1 ,查看结果,并注意 First 和 Single 使用的 SQL 语句,如下所示的输出:
Enter a product ID: 1
Connection: Data Source=C:\cs13net9\Chapter10\WorkingWithEFCore\bin\Debug\net9.0\Northwind.db
dbug: 9/17/2023 18:04:14.210 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)
Executing DbCommand [Parameters=[@__id_0='1'], CommandType='Text', CommandTimeout='30']
SELECT "p"."ProductId", "p"."CategoryId", "p"."UnitPrice", "p"."Discontinued", "p"."ProductName", "p"."UnitsInStock"
FROM "Products" AS "p"
WHERE "p"."ProductId" > @__id_0
LIMIT 1
Info > First: Chang
dbug: 9/17/2023 18:04:14.286 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)
Executing DbCommand [Parameters=[@__id_0='1'], CommandType='Text', CommandTimeout='30']
SELECT "p"."ProductId", "p"."CategoryId", "p"."UnitPrice", "p"."Discontinued", "p"."ProductName", "p"."UnitsInStock"
FROM "Products" AS "p"
WHERE "p"."ProductId" > @__id_0
LIMIT 2
Info > Single: Chang
请注意,这两种方法执行的 SQL 语句是相同的,除了前面代码中突出显示的 LIMIT 子句。对于 First ,它设置了 LIMIT 1 ,但对于 Single ,它设置了 LIMIT 2 。为什么?
对于 First ,查询可以匹配一个或多个实体,只有第一个会被返回。如果没有匹配项,将抛出异常,但如果没有匹配项,您可以调用 FirstOrDefault 以返回 null 。
对于 Single ,查询必须仅匹配一个实体并将其返回。如果有多个匹配,则必须抛出异常。但是,EF Core 知道是否有多个匹配的唯一方法是请求多个并进行检查。因此,它必须设置 LIMIT 2 并检查是否有第二个实体匹配。
良好实践:如果您不需要确保只有一个实体匹配,请使用 First 而不是 Single 以避免检索到两个记录。
使用 Like 进行模式匹配
EF Core 支持常见的 SQL 语句,包括 Like 用于模式匹配:
- 在 Program.Queries.cs 中,添加一个名为 QueryingWithLike 的方法,如下代码所示,并注意以下事项:我们已启用日志记录。我们提示用户输入产品名称的一部分,然后使用 EF.Functions.Like 方法在 ProductName 属性中进行搜索。对于每个匹配的产品,我们输出其名称、库存以及是否已停产:
private static void QueryingWithLike()
{
using NorthwindDb db = new();
SectionTitle("Pattern matching with LIKE");
Write("Enter part of a product name: ");
string? input = ReadLine();
if (string.IsNullOrWhiteSpace(input))
{
Fail("You did not enter part of a product name.");
return;
}
IQueryable<Product>? products = db.Products?
.Where(p => EF.Functions.Like(p.ProductName, #34;%{input}%"));
if (products is null || !products.Any())
{
Fail("No products found.");
return;
}
foreach (Product p in products)
{
WriteLine("{0} has {1} units in stock. Discontinued: {2}",
p.ProductName, p.Stock, p.Discontinued);
}
}
- 在 Program.cs 中,注释掉现有的方法并调用 QueryingWithLike 。
- 运行代码,输入部分产品名称,例如 che ,并查看结果,如下所示的编辑输出:
Enter part of a product name: che
dbug: 07/16/2023 13:03:42.793 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)
Executing DbCommand [Parameters=[@__Format_1='%che%' (Size = 5)], CommandType='Text', CommandTimeout='30']
SELECT "p"."ProductId", "p"."CategoryId", "p"."UnitPrice", "p"."Discontinued", "p"."ProductName", "p"."UnitsInStock"
FROM "Products" AS "p"
WHERE "p"."ProductName" LIKE @__Format_1
Chef Anton's Cajun Seasoning has 53 units in stock. Discontinued: False
Chef Anton's Gumbo Mix has 0 units in stock. Discontinued: True
Queso Manchego La Pastora has 86 units in stock. Discontinued: False
更多信息:您可以通过 Like 在 https://learn.microsoft.com/en-us/dotnet/framework/data/adonet/ef/language-reference/like-entity-sql 学习有关通配符的更多内容。
在查询中生成随机数
EF Core 6 引入了一个有用的函数 EF.Functions.Random ,该函数映射到一个数据库函数,返回一个介于 0.0 和 1.0 之间(不包括 0.0 和 1.0)的伪随机实数。
例如,假设您正在开发一个测验或调查应用程序,需要在每次用户参与时以随机顺序显示问题。您可以使用 EF.Functions.Random() 从数据库中直接获取随机选择的问题,如以下代码所示:
var randomQuestions = await db.Questions
.OrderBy(q => EF.Functions.Random())
.Take(10); // Select 10 random questions.
在开发和测试阶段,生成随机数据可以用于模拟各种场景。例如,通过随机选择大约一半的产品来创建用于性能测试的随机数据集或生成用于单元测试的随机行集,如以下代码所示:
var randomDataSample = await db.Products
.Where(d => EF.Functions.Random() > 0.5);
定义全局过滤器
Northwind 产品可以被停产,因此确保停产的产品在结果中永远不会被返回可能是有用的,即使程序员在查询中不使用 Where 来过滤它们
- 在 NorthwindDb.cs 中,在 OnModelCreating 方法的底部,添加一个全局过滤器以移除停产产品,如以下代码所示:
// A global filter to remove discontinued products.
modelBuilder.Entity<Product>()
.HasQueryFilter(p => !p.Discontinued);
- 在 Program.cs 中,取消对 QueryingWithLike 的注释,并注释掉所有其他方法调用。
- 运行代码,输入部分产品名称 che ,查看结果,并注意到 Chef Anton's Gumbo Mix 现在缺失。这是因为生成的 SQL 语句包含了对 Discontinued 列的过滤,如下输出中所示的高亮部分:
Enter part of a product name: che
dbug: 05/03/2022 13:34:27.290 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)
Executing DbCommand [Parameters=[@__Format_1='%che%' (Size = 5)], CommandType='Text', CommandTimeout='30']
SELECT "p"."ProductId", "p"."CategoryId", "p"."UnitPrice", "p"."Discontinued", "p"."ProductName", "p"."UnitsInStock"
FROM "Products" AS "p"
WHERE
NOT ("p"."Discontinued") AND
("p"."ProductName" LIKE @__Format_1)
Chef Anton's Cajun Seasoning has 53 units in stock. Discontinued? False
Queso Manchego La Pastora has 86 units in stock. Discontinued? False
Gumb?r Gummib?rchen has 15 units in stock. Discontinued? False
SQL SELECT 查询
通常,您可以使用 LINQ 表达您所需的所有查询。但在无法做到的情况下,您可以使用 FromSql 及其相关方法。
FromSql 在 EF Core 7 中引入。如果您需要在 EF Core 6 或更早版本中执行原始 SQL,则必须使用 FromSqlInterpolated 方法。
FromSql 方法允许您对数据库执行原始 SQL 查询,并将结果映射到您的实体类。 FromSql 可用于执行 SELECT 查询,这些查询返回实体类型或不属于 EF Core 模型的类型。
FromSql 方法在以下情况下特别有用:
- 它允许您运行复杂的 SQL 查询,这在使用 LINQ 时可能不可行。
- 有时候,对于某些类型的查询,原始 SQL 的性能可能优于 LINQ。
- 如果您正在使用需要执行特定 SQL 查询的遗留系统。
- 您可以执行返回实体的存储过程。
传递给 FromSql 的参数必须是 FormattableString ,而不仅仅是常规的 string 值。这是为了强制执行安全参数化。使用插值 string 格式传递参数值。
让我们看一些例子:
- 在 Program.Queries.cs 中,添加一个名为 GetProductUsingSql 的方法,如下代码所示:
private static void GetProductUsingSql()
{
using NorthwindDb db = new();
SectionTitle("Get product using SQL");
int? rowCount = db.Products?.Count();
if (rowCount is null)
{
Fail("Products table is empty.");
return;
}
int productId = 1;
Product? p = db.Products?.FromSql(
#34;SELECT * FROM Products WHERE ProductId = {
productId}").FirstOrDefault();
if (p is null)
{
Fail("Product not found.");
return;
}
WriteLine(#34;Product: {p.ProductId} - {p.ProductName}");
}
- 在 Program.cs 中,添加对 GetProductUsingSql 的调用。
- 运行代码并查看结果,如下所示的输出:
dbug: 7/27/2024 14:47:07.515 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)
Executing DbCommand [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT COUNT(*)
FROM "Products" AS "p"
WHERE NOT ("p"."Discontinued")
dbug: 7/27/2024 14:47:07.582 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command)
Executing DbCommand [Parameters=[p0='1'], CommandType='Text', CommandTimeout='30']
SELECT "n"."ProductId", "n"."CategoryId", "n"."UnitPrice", "n"."Discontinued", "n"."ProductName", "n"."UnitsInStock"
FROM (
SELECT * FROM Products WHERE ProductId = @p0
) AS "n"
WHERE NOT ("n"."Discontinued")
LIMIT 1
Product: 1 – Chai
FromSql 只能在 DbSet<T> 上调用,而不能在 LINQ 查询上调用。
您可以使 SQL 在需要的情况下更加动态。例如,如果列的名称可能会更改,以及值也可能会更改,那么您可以使用 FromSqlRaw 。但请注意!您有责任确保这个 string 值是安全的,特别是如果它来自不受信任的来源。这涉及识别特殊字符,如分号、注释和其他 SQL 结构,然后正确转义或拒绝这些输入,以防止潜在的安全风险。
更多信息:您可以在 https://learn.microsoft.com/en-us/ef/core/querying/sql-queries#dynamic-sql-and-parameters 上了解有关动态 SQL 和参数的更多信息。
您现在已经看到了使用 EF Core 查询数据的许多常见方法。在某些在线部分,您可以查看数据是如何加载和跟踪的,以及您为什么可能想要控制 EF Core 如何执行这些操作。
相关推荐
- 5分钟搭建公网https网页文件服务器,免费权威TLS证书
-
请关注本头条号,每天坚持更新原创干货技术文章。如需学习视频,请在微信搜索公众号“智传网优”直接开始自助视频学习前言本文主要讲解如何快速搭建一个https网页文件服务器,并免费申请权威机构颁发的tls证...
- nginx负载均衡配置(nginx负载均衡配置两个程序副本)
-
Nginx是什么没有听过Nginx?那么一定听过它的“同行”Apache吧!Nginx同Apache一样都是一种WEB服务器。基于REST架构风格,以统一资源描述符(UniformResources...
- 19《Nginx 入门教程》Nginx综合实践
-
今天我们将基于Nginx完成两个比较有用的场景,但是用到的Nginx的配置非常简单。内部Yum源搭建内部Pip源搭建1.实验环境ceph1centos7.6内网ip:172.16....
- Nginx性能调优与优化指南(nginx优化配置大全)
-
Nginx性能调优需要结合服务器硬件资源、业务场景和负载特征进行针对性优化。以下是一些关键优化方向和具体配置示例:一、Nginx配置优化1.进程与连接数优化nginxworker_process...
- C++后端开发必须彻底搞懂Nginx,从原理到实战(高级篇)
-
本文为Nginx实操高级篇。通过配置Nginx配置文件,实现正向代理、反向代理、负载均衡、Nginx缓存、动静分离和高可用Nginx6种功能,并对Nginx的原理作进一步的解析。当需...
- 【Nginx】史上最全的Nginx配置详解
-
Nginx服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里,http块又包括http全局块和server块。Nginx是非常重要的负载均衡中间件,被广泛应用于大型...
- 【Nginx】Nginx 4种常见配置实例(nginx基本配置与参数说明)
-
本文主要介绍nginx4种常见的配置实例。Nginx实现反向代理;Nginx实现负载均衡;Nginx实现动静分离;Nginx实现高可用集群;Nginx4种常见配置实例如下:一、Nginx反向代理配...
- 使用nginx+allure管理自动化测试报告
-
allure在自动化测试中经常用来生成漂亮的报告,但是网上及官网上给出的例子都仅仅是针对单个测试用例文件的形式介绍的,实际使用中,自动化测试往往需要包含不止一个产品或项目,本文介绍如何使用nginx+...
- nginx配置文件详解(nginx配置文件详解高清版)
-
Nginx是一个强大的免费开源的HTTP服务器和反向代理服务器。在Web开发项目中,nginx常用作为静态文件服务器处理静态文件,并负责将动态请求转发至应用服务器(如Django,Flask,et...
- SpringCloud Eureka-服务注册与发现
-
1.Eureka介绍1.1学习Eureka前的说明目前主流的服务注册&发现的组件是Nacos,但是Eureka作为老牌经典的服务注册&发现技术还是有必要学习一下,原因:(1)一些早期的分布式微服...
- 微服务 Spring Cloud 实战 Eureka+Gateway+Feign+Hystrix
-
前言我所在项目组刚接到一个微服务改造需求,技术选型为SpringCloud,具体需求是把部分项目使用SpringCloud技术进行重构。本篇文章中介绍了Eureka、Gateway、Fe...
- 深度剖析 Spring Cloud Eureka 底层实现原理
-
你作为一名互联网大厂后端技术开发人员,在构建分布式系统时,是不是常常为服务的注册与发现而头疼?你是否好奇,像SpringCloudEureka这样被广泛使用的组件,它的底层实现原理到底是怎样的...
- 热爱生活,喜欢折腾。(很热爱生活)
-
原文是stackoverflow的一则高票回答,原文链接可能之前也有人翻译过,但是刚好自己也有疑惑,所以搬运一下,个人水平有限所以可能翻译存在误差,欢迎指正(如侵删)。尽管classmethod和st...
- GDB调试的高级技巧(详细描述gdb调试程序的全过程)
-
GDB是我们平时调试c/c++程序的利器,查起复杂的bug问题,比打印大法要好得多,但是也不得不说,gdb在默认情况下用起来并不是很好用,最近学习到几个高级点的技巧,分享下:一美化打印先上个例子...
- Arduino 实例(二十三)Arduino 给Python 编译器发送信息
-
1首先Python需要安装Pyserial库,在命令提示符中输入pipintallpyserial若是遇到提示‘pip‘不是内部或外部命令,也不是可运行的程序或批处理文件,则需要设置环境变...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- skip-name-resolve (63)
- linuxlink (65)
- pythonwget (67)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- oracle时间戳转换日期 (64)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)