You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
> <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSql*> was introduced in EF Core 7.0. When using older versions, use <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSqlInterpolated*> instead.
24
28
25
29
SQL queries can be used to execute a stored procedure which returns entity data:
@@ -41,17 +49,35 @@ SQL queries can be used to execute a stored procedure which returns entity data:
41
49
42
50
The following example passes a single parameter to a stored procedure by including a parameter placeholder in the SQL query string and providing an additional argument:
While this syntax may look like regular C# [string interpolation](/dotnet/csharp/language-reference/tokens/interpolated), the supplied value is wrapped in a `DbParameter` and the generated parameter name inserted where the `{0}` placeholder was specified. This makes <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSql*> safe from SQL injection attacks, and sends the value efficiently and correctly to the database.
47
61
48
62
When executing stored procedures, it can be useful to use named parameters in the SQL query string, especially when the stored procedure has optional parameters:
If you need more control over the database parameter being sent, you can also construct a `DbParameter` and supply it as a parameter value. This allows you to set the precise database type of the parameter, or facets such as its size, precision or length:
@@ -76,7 +102,14 @@ First, it's important to consider the implications of dynamically constructing a
76
102
77
103
If you've decided you do want to dynamically construct your SQL, you'll have to use <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSqlRaw*>, which allows interpolating variable data directly into the SQL string, instead of using a database parameter:
.FromSqlRaw($"SELECT * FROM [Blogs] WHERE {columnName} = @columnValue", columnValue)
111
+
.ToList();
112
+
```
80
113
81
114
In the above code, the column name is inserted directly into the SQL, using C# string interpolation. It is your responsibility to make sure this string value is safe, sanitizing it if it comes from an unsafe origin; this means detecting special characters such as semicolons, comments, and other SQL constructs, and either escaping them properly or rejecting such inputs.
82
115
@@ -90,7 +123,15 @@ On the other hand, the column value is sent via a `DbParameter`, and is therefor
90
123
91
124
You can compose on top of the initial SQL query using LINQ operators; EF Core will treat your SQL as a subquery and compose over it in the database. The following example uses a SQL query that selects from a Table-Valued Function (TVF). And then composes on it using LINQ to do filtering and sorting.
.FromSql($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
156
+
.Include(b=>b.Posts)
157
+
.ToList();
158
+
```
111
159
112
160
Composing with LINQ requires your SQL query to be composable, since EF Core will treat the supplied SQL as a subquery. Composable SQL queries generally begin with the `SELECT` keyword, and cannot contain SQL features that aren't valid in a subquery, such as:
113
161
@@ -123,7 +171,14 @@ Queries that use <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensio
123
171
124
172
The following example uses a SQL query that selects from a Table-Valued Function (TVF), then disables change tracking with the call to [`AsNoTracking`](xref:core/querying/tracking#no-tracking-queries):
.FromSql($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
179
+
.AsNoTracking()
180
+
.ToList();
181
+
```
127
182
128
183
## Querying scalar (non-entity) types
129
184
@@ -205,7 +260,12 @@ var overAverageIds = context.Database
205
260
206
261
In some scenarios, it may be necessary to execute SQL which does not return any data, typically for modifying data in the database or calling a stored procedure which doesn't return any result sets. This can be done via <xref:Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSql*>:
varrowsModified=context.Database.ExecuteSql($"UPDATE [Blogs] SET [Url] = NULL");
267
+
}
268
+
```
209
269
210
270
This executes the provided SQL and returns the number of rows modified. <xref:Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSql*> protects against SQL injection by using safe parameterization, just like <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSql*>, and <xref:Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.ExecuteSqlRaw*> allows for dynamic construction of SQL queries, just like <xref:Microsoft.EntityFrameworkCore.RelationalQueryableExtensions.FromSqlRaw*> does for queries.
0 commit comments