Ham SQL SorgularıRaw SQL Queries

Entity Framework Core, ilişkisel bir veritabanıyla çalışırken ham SQL sorgularına düşmenizi sağlar.Entity Framework Core allows you to drop down to raw SQL queries when working with a relational database. İstediğiniz sorgu LINQ kullanılarak ifade edilenemiyorsa Ham SQL sorguları yararlıdır.Raw SQL queries are useful if the query you want can't be expressed using LINQ. Bir LINQ sorgusu kullanarak verimsiz bir SQL sorgusu neden olduğunda Ham SQL sorguları da kullanılır.Raw SQL queries are also used if using a LINQ query is resulting in an inefficient SQL query. Raw SQL sorguları, normal varlık türlerini veya modelinizin bir parçası olan anahtarsız varlık türlerini döndürebilir.Raw SQL queries can return regular entity types or keyless entity types that are part of your model.

İpucu

Bu makalenin örneğini GitHub'da görüntüleyebilirsiniz.You can view this article's sample on GitHub.

Temel ham SQL sorgularıBasic raw SQL queries

Ham bir FromSqlRaw SQL sorgusunu temel alan bir LINQ sorgusu başlatmak için uzantı yöntemini kullanabilirsiniz.You can use the FromSqlRaw extension method to begin a LINQ query based on a raw SQL query. FromSqlRawyalnızca doğrudan sorgu köklerinde DbSet<>kullanılabilir.FromSqlRaw can only be used on query roots, that is directly on the DbSet<>.

var blogs = context.Blogs
    .FromSqlRaw("SELECT * FROM dbo.Blogs")
    .ToList();

Raw SQL sorguları depolanan yordamı yürütmek için kullanılabilir.Raw SQL queries can be used to execute a stored procedure.

var blogs = context.Blogs
    .FromSqlRaw("EXECUTE dbo.GetMostPopularBlogs")
    .ToList();

Parametreleri geçirmePassing parameters

Uyarı

Her zaman ham SQL sorguları için parametreleştirme kullanınAlways use parameterization for raw SQL queries

Kullanıcı tarafından sağlanan değerleri ham bir SQL sorgusuna sokarken, SQL enjeksiyon saldırılarından kaçınmak için dikkatli olunmalıdır.When introducing any user-provided values into a raw SQL query, care must be taken to avoid SQL injection attacks. Bu tür değerlerin geçersiz karakterler içermediğini doğrulamanın yanı sıra, her zaman SQL metninden ayrı değerleri gönderen parametrelendirmekullanın.In addition to validating that such values don't contain invalid characters, always use parameterization which sends the values separate from the SQL text.

Özellikle, kullanıcı tarafından sağlanan doğrulanmış olmayan değerlere$""sahip, hiçbir zaman bir sıkıştırılmış FromSqlRaw ExecuteSqlRawveya enterpolasyonlu dizeyi () hiçbir zaman geçemez.In particular, never pass a concatenated or interpolated string ($"") with non-validated user-provided values into FromSqlRaw or ExecuteSqlRaw. Ve FromSqlInterpolated ExecuteSqlInterpolated yöntemler, string enterpolasyon sözdizimini SQL enjeksiyon saldırılarına karşı koruyacak şekilde kullanmaolanağı sağlar.The FromSqlInterpolated and ExecuteSqlInterpolated methods allow using string interpolation syntax in a way that protects against SQL injection attacks.

Aşağıdaki örnek, SQL sorgu dizesi bir parametre yer tutucusu ekleyerek ve ek bir bağımsız değişken sağlayarak depolanan yordamı tek bir parametre geçer.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. Bu sözdizimi sözdizimi gibi String.Format görünse de, sağlanan DbParameter değer a'ya sarılır ve {0} yer tutucunun belirtildiği yere oluşturulan parametre adı eklenir.While this syntax may look like String.Format syntax, the supplied value is wrapped in a DbParameter and the generated parameter name inserted where the {0} placeholder was specified.

var user = "johndoe";

var blogs = context.Blogs
    .FromSqlRaw("EXECUTE dbo.GetMostPopularBlogsForUser {0}", user)
    .ToList();

FromSqlInterpolatedbenzer FromSqlRaw dir, ancak dize enterpolasyon sözdizimini kullanmanıza olanak sağlar.FromSqlInterpolated is similar to FromSqlRaw but allows you to use string interpolation syntax. Gibi FromSqlRaw, FromSqlInterpolated sadece sorgu kökleri kullanılabilir.Just like FromSqlRaw, FromSqlInterpolated can only be used on query roots. Önceki örnekte olduğu gibi, değer a DbParameter dönüştürülür ve SQL enjeksiyonuna karşı savunmasız değildir.As with the previous example, the value is converted to a DbParameter and isn't vulnerable to SQL injection.

Not

Önce sürüm 3.0 FromSqlRaw FromSqlInterpolated ve iki overloads adlı FromSqledildi .Prior to version 3.0, FromSqlRaw and FromSqlInterpolated were two overloads named FromSql. Daha fazla bilgi için önceki sürümler bölümünebakın.For more information, see the previous versions section.

var user = "johndoe";

var blogs = context.Blogs
    .FromSqlInterpolated($"EXECUTE dbo.GetMostPopularBlogsForUser {user}")
    .ToList();

Ayrıca bir DbParameter oluşturup parametre değeri olarak da sağlayabilirsiniz.You can also construct a DbParameter and supply it as a parameter value. Dize yer tutucusu yerine normal bir SQL parametre FromSqlRaw yer tutucukullanıldığından, güvenli bir şekilde kullanılabilir:Since a regular SQL parameter placeholder is used, rather than a string placeholder, FromSqlRaw can be safely used:

var user = new SqlParameter("user", "johndoe");

var blogs = context.Blogs
    .FromSqlRaw("EXECUTE dbo.GetMostPopularBlogsForUser @user", user)
    .ToList();

FromSqlRawSQL sorgu dizesinde adlandırılmış parametreleri kullanmanıza olanak tanır, bu da depolanan bir yordamın isteğe bağlı parametreleri olduğunda yararlıdır:FromSqlRaw allows you to use named parameters in the SQL query string, which is useful when a stored procedure has optional parameters:

var user = new SqlParameter("user", "johndoe");

var blogs = context.Blogs
    .FromSqlRaw("EXECUTE dbo.GetMostPopularBlogsForUser @filterByUser=@user", user)
    .ToList();

LINQ ile besteComposing with LINQ

LINQ işleçlerini kullanarak ilk ham SQL sorgusunun üstüne oluşturabilirsiniz.You can compose on top of the initial raw SQL query using LINQ operators. EF Core bunu alt sorgu olarak ele alacak ve veritabanında üzerinde oluşturacaktır.EF Core will treat it as subquery and compose over it in the database. Aşağıdaki örnekte, Tablo Değeri Olan İşlev'den (TVF) seçim yapan ham bir SQL sorgusu kullanır.The following example uses a raw SQL query that selects from a Table-Valued Function (TVF). Ve sonra filtreleme ve sıralama yapmak için LINQ kullanarak üzerine oluşturur.And then composes on it using LINQ to do filtering and sorting.

var searchTerm = ".NET";

var blogs = context.Blogs
    .FromSqlInterpolated($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
    .Where(b => b.Rating > 3)
    .OrderByDescending(b => b.Rating)
    .ToList();

Yukarıdaki sorgu aşağıdaki SQL oluşturur:Above query generates following SQL:

SELECT [b].[BlogId], [b].[OwnerId], [b].[Rating], [b].[Url]
FROM (
    SELECT * FROM dbo.SearchBlogs(@p0)
) AS [b]
WHERE [b].[Rating] > 3
ORDER BY [b].[Rating] DESC

Yöntem, Include diğer LINQ sorgusunda olduğu gibi ilgili verileri de eklemek için kullanılabilir:The Include method can be used to include related data, just like with any other LINQ query:

var searchTerm = ".NET";

var blogs = context.Blogs
    .FromSqlInterpolated($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
    .Include(b => b.Posts)
    .ToList();

EF Core, sağlanan SQL'i bir alt sorgu olarak ele alacağı için, LINQ ile beste yapmak için ham SQL sorgunuzun birleştirilebilir olmasını gerektirir.Composing with LINQ requires your raw SQL query to be composable since EF Core will treat the supplied SQL as a subquery. Üzerinde oluşturulabilen SQL sorguları SELECT anahtar sözcükile başlar.SQL queries that can be composed on begin with the SELECT keyword. Ayrıca, SQL geçirilen gibi bir alt sorgu üzerinde geçerli olmayan herhangi bir karakter veya seçenek içermemelidir:Further, SQL passed shouldn't contain any characters or options that aren't valid on a subquery, such as:

  • İzleyen bir yarı kolonA trailing semicolon
  • SQL Server'da, sorgu düzeyi ipucu (örneğin, OPTION (HASH JOIN))On SQL Server, a trailing query-level hint (for example, OPTION (HASH JOIN))
  • ORDER BY SQL Server'da, OFFSET 0 TOP 100 PERCENT SELECT yan tümcede OR ile kullanılmayan bir yan tümceOn SQL Server, an ORDER BY clause that isn't used with OFFSET 0 OR TOP 100 PERCENT in the SELECT clause

SQL Server, depolanan yordam çağrıları üzerinde bir araya gelmekiçin izin vermez, bu nedenle böyle bir çağrıya ek sorgu işleçleri uygulama girişimi geçersiz SQL'e neden olur.SQL Server doesn't allow composing over stored procedure calls, so any attempt to apply additional query operators to such a call will result in invalid SQL. EF AsEnumerable AsAsyncEnumerable Core'un FromSqlRaw FromSqlInterpolated depolanan bir yordam üzerinde oluşturmaya çalışmadığından emin olmak için hemen sonra veya yöntem kullanın.Use AsEnumerable or AsAsyncEnumerable method right after FromSqlRaw or FromSqlInterpolated methods to make sure that EF Core doesn't try to compose over a stored procedure.

Değişiklik İzlemeChange Tracking

FromSqlRaw Veya FromSqlInterpolated yöntemleri kullanan sorgular, EF Core'daki diğer LINQ sorguları yla aynı değişiklik izleme kurallarını izler.Queries that use the FromSqlRaw or FromSqlInterpolated methods follow the exact same change tracking rules as any other LINQ query in EF Core. Örneğin, sorgu varlık türlerini projeleri ise, sonuçlar varsayılan olarak izlenir.For example, if the query projects entity types, the results will be tracked by default.

Aşağıdaki örnek, Tablo Değeri Olan İşlev'den (TVF) seçim yapan ham bir SQL sorgusu AsNoTrackingkullanır, ardından aşağıdaki çağrıyla izlemeyi değiştirir:The following example uses a raw SQL query that selects from a Table-Valued Function (TVF), then disables change tracking with the call to AsNoTracking:

var searchTerm = ".NET";

var blogs = context.Blogs
    .FromSqlInterpolated($"SELECT * FROM dbo.SearchBlogs({searchTerm})")
    .AsNoTracking()
    .ToList();

SınırlamalarLimitations

Ham SQL sorgularını kullanırken dikkat edilmesi gereken birkaç sınırlama vardır:There are a few limitations to be aware of when using raw SQL queries:

  • SQL sorgusu, varlık türünün tüm özellikleri için veri döndürmelidir.The SQL query must return data for all properties of the entity type.
  • Sonuç kümesindeki sütun adları, özelliklerin eşlenen sütun adlarıyla eşleşmelidir.The column names in the result set must match the column names that properties are mapped to. Bu davranışın EF6'dan farklı olduğunu unutmayın.Note this behavior is different from EF6. EF6, ham SQL sorguları için sütun eşleme özelliğini göz ardı etti ve sonuç kümesi sütun adları özellik adlarıyla eşleşmek zorunda kaldı.EF6 ignored property to column mapping for raw SQL queries and result set column names had to match the property names.
  • SQL sorgusu ilgili verileri içeremez.The SQL query can't contain related data. Ancak, çoğu durumda ilgili verileri döndürmek için Include işleci kullanarak sorgunun üstüne oluşturabilirsiniz (bkz. ilgili verileri dahil etme).However, in many cases you can compose on top of the query using the Include operator to return related data (see Including related data).

Önceki sürümlerPrevious versions

EF Core version 2.2 and earlier had two overloads of method named FromSql, which behaved in the same way as the newer FromSqlRaw and FromSqlInterpolated.EF Core version 2.2 and earlier had two overloads of method named FromSql, which behaved in the same way as the newer FromSqlRaw and FromSqlInterpolated. Amaç enterpolasyonlu dize yöntemini aramakken yanlışlıkla ham dize yöntemini aramak kolaydı.It was easy to accidentally call the raw string method when the intent was to call the interpolated string method, and the other way around. Yanlışlıkla yanlış aşırı yükleme çağrısı, sorguların olması gerekirken parametrelendirilememelerine neden olabilir.Calling wrong overload accidentally could result in queries not being parameterized when they should have been.