在用.net core進行數據庫訪問,需要處理一些比較復雜的查詢,就不得不用原生的SQL查詢了,然而EF Core 和EF6 的原生sql查詢存在很大的差異。
在EF6中我們用SqlQuery和ExecuteSqlCommand進行sql語句的執行,而在EF Core中我們則使用FromSql和ExecuteSqlCommand
一.ExecuteSqlCommand(這兩者沒什么太大的區別)
Company08Entities db = new Company08Entities(); string sql = string.Format("update Cars set IsPub='是',PubTime='{1}' where Id in ({0})",ids,DateTime.Now); int res = db.Database.ExecuteSqlCommand(sql); //返回受影響的行數 if (res>0) { return Json(new UIResult(true,"發布成功!")); } else { return Json(new UIResult(false,"發布失敗,請重試!")); }
二.數據庫查詢語句兩者的差別就太大了,這里我會詳細舉例說明
1.在EF6中使用SqlQuery進行查詢以及聯和Linq進行分頁
Company08Entities db = new Company08Entities(); string sql = "select c.* from Cars c join ResCommend r on c.Id=r.ResId where r.Posld=2 and DeadLine>GETDATE() and c.IsPub='是'";
var res = db.Database.SqlQuery<Cars>(sql); var list = res.Skip((pn - 1) * pz).Take(pz).ToList(); //其中pn為頁碼,pz為頁大小
2.在EF Core中我們使用FromSql
新版本需要安裝:Microsoft.EntityFrameworkCore.Relational 這個包,而且還需要引用 Microsoft.EntityFrameworkCore這個命名空間
private Company08Context db = null; public ProductController(Company08Context context) { this.db = context; } String sql =string.Format($"select c.* from Cars c join ResCommend r on c.Id=r.ResId where r.Posld=2 and DeadLine>GETDATE() and c.IsPub='是'"); //var res = db.Cars.FromSql(sql); 已過時 var res = db.Cars.FromSqlRaw(sql); var list = res.Skip((pn-1)*pz).Take(pz).ToList();
這中使用 LINQ 運算符在初始的原始 SQL 查詢基礎上進行組合會出現以下這種問題
這是因為使用 LINQ 運算符在初始的原始 SQL 查詢基礎上進行組合。 EF Core 將其視為子查詢,並在數據庫中對其進行組合,導致查詢出錯
解決方案就是阻止查詢運算操作的組合,在 FromSql
方法之后立即使用 AsEnumerable
或 AsAsyncEnumerable
方法,確保 EF Core 不會嘗試對存儲過程進行組合。
String sql =string.Format($"select c.* from Cars c join ResCommend r on c.Id=r.ResId where r.Posld=2 and DeadLine>GETDATE() and c.IsPub='是'"); // var res = db.Cars.FromSql(sql).AsEnumerable(); //新版中 FromSql 已過時 var list=res.Cars.FromSqlRaw(sql); var list = res.Skip((pn-1)*pz).Take(pz).ToList();