表結構
在具體內容開始之前,我們先簡單說明一下要使用的表結構,
public class Category
{
public int CategoryID
{
get;
set;
}
public string CategoryName
{
get;
set;
}
}
在Category定義了兩個欄位:CategoryID、CategoryName,
public class SampleDbContext: DbContext
{
public virtual DbSet < Category > Categories
{
get;
set;
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
var sqlConnectionStringBuilder = new SqlConnectionStringBuilder
{
DataSource = "10.0.1.5", InitialCatalog = "TestDataBase", UserID = "sa", Password = "******"
};
optionsBuilder.UseSqlServer(sqlConnectionStringBuilder.ConnectionString);
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
EntityTypeBuilder < Category > entityTypeBuilder = modelBuilder.Entity < Category > ();
entityTypeBuilder.ToTable("Category");
entityTypeBuilder.HasKey(e => e.CategoryID);
entityTypeBuilder.Property(e => e.CategoryID).UseSqlServerIdentityColumn();
}
}
我們使用SampleDbContext來訪問資料庫,
FromSql執行SQL陳述句
Entity Framework Core為DbSet<TEntity>提供了一個擴展方法FromSql,用于執行SQL陳述句或存盤程序,以下示例使用FromSql加載所有的資料,
using(var dataContext = new SampleDbContext())
{
var query = dataContext.Categories.FromSql("select * from Category");
var result = query.ToList();
}
對于帶有引數的SQL陳述句,我們使用C# 6 語法將SQL寫成如下:
using(var dataContext = new SampleDbContext())
{
var categoryID = 1;
var query = dataContext.Categories.FromSql($ "select * from Category where CategoryID={categoryID}");
var result = query.ToList();
}
注意:這里不是直接使用拼接的方式處理SQL,而是轉化為引數化的SQL陳述句,這有助于防止SQL注入攻擊,我們可以使用SQL Server Profiler幫我們驗證:
exec sp_executesql N 'select * from Category where CategoryID=@p0 ', N '@p0 int', @p0 = 1

如果您不使用C# 6的語法特征,我們必須使用 @p0、@p1 ... @pn 做為SQL陳述句的引數:
using(var dataContext = new SampleDbContext())
{
var categoryID = 1;
var categoryName = "Product";
var query = dataContext.Categories.FromSql("select * from Category where CategoryID=@p0 and CategoryName=@p1"
categoryID, categoryName);
var result = query.ToList();
Assert.NotNull(result);
}
在上述SQL陳述句中中,將@p0映射到categoryID、@ p1映射到categoryName,
FromSql擴展方法回傳的是IQueryable<TEntity>物件,要們還可以接著使用一些Linq的方法,示例如下:
using(var dataContext = new SampleDbContext())
{
var categoryID = 1;
var query = dataContext.Categories.FromSql("select * from Category").Where(item => item.CategoryID == categoryID).OrderBy(item => item.CategoryName);
var result = query.ToList();
}
不過在這里,使用的是子查詢,使用SQL Server Profiler捕獲到的SQL陳述句如下:
exec sp_executesql N 'SELECT [item].[CategoryID], [item].[CategoryName] FROM ( select * from Category ) AS [item] WHERE [item].[CategoryID] = @__categoryID_1 ORDER BY [item].[CategoryName]', N '@__categoryID_1 int', @__categoryID_1 = 1
提示:使用
FromSql時,需要在執行的SQL陳述句中回傳所有列,并且列名必須與物體屬性名相匹配,否則執行會出錯,
FromSql執行存盤程序
存盤程序與SQL陳述句寫法基本一致,使用存盤程序的示例如下:
using(var dataContext = new SampleDbContext())
{
var categoryID = 1;
var query = dataContext.Categories.FromSql($ "GetCategoryById {categoryID}");
var result = query.ToList();
Assert.NotNull(result);
}
這些引數的順序必須與存盤程序引數的順序一致,
提示:使用
FromSql執行存盤程序時,如果使用'Where'、'OrderBy'等Linq語法,這些操作不會生成SQL陳述句,而是在.Net中對存盤程序回傳的集合進行過濾與排序,
ExecuteSqlCommand
在DbContext暴露了一個Database屬性,它包括一個ExecuteSqlCommand方法,此方法回傳一個整數,表示執行的SQL陳述句影響的行數,有效的操作是INSERT、UPDATE和DELETE,不能用于回傳物體,
using(var dataContext = new SampleDbContext())
{
var categoryID = 1;
var categoryName = "Product";
var result = dataContext.Database.ExecuteSqlCommand($ "UPDATE dbo.Category SET CategoryName={categoryName} WHERE CategoryID={categoryID}");
}
總結
本節介紹了Entity Framework Core中執行SQL陳述句和存盤程序的幾種方法, 希望對您有幫助,謝謝!
原文地址:https://www.cnblogs.com/tdfblog/p/execute-sql-stored-procedure-in-entity-framework-core.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/20499.html
標籤:.NET Core
