EF Core中執行Sql語句查詢操做之FromSql,ExecuteSqlCommand,SqlQuery

1、目前EF Core的版本爲V2.1html

相比較EF Core v1.0 目前已經增長了很多功能。sql

EF Core除了經常使用的增刪改模型操做,Sql語句在很多項目中是不能避免的。ide

在EF Core中上下文,能夠返貨DbConnection ,執行sql語句。這是最底層的操做方式,代碼寫起來仍是挺多的。post

初次以外 EF Core中還支持 FromSql,ExecuteSqlCommand 連個方法,用於更方便的執行Sql語句。this

另外,目前版本的EF Core 不支持SqlQuery,可是咱們能夠本身擴展一個。坐等升級之後支持吧。spa

1.FromSql,執行列表查詢code

public static IQueryable<TEntity> FromSql<TEntity>([NotNullAttribute] this IQueryable<TEntity> source, 
[NotParameterized] RawSqlString sql,
[NotNullAttribute] params object[] parameters) where TEntity : class;

這種方式,僅用於當前上線文中註冊的 模型對象。htm

對於上下文DbSet<T>中沒有定義的不起做用。對象

示例代碼1:blog

    //執行sql查詢語句 FromSql()
    QLLB_SWXContext _Context = new QLLB_SWXContext();
    string sql = "select * from Article where CategoryID=1;";
    List<Article> list = _Context.Article.FromSql(sql).ToList();
    foreach (var item in list)
    {
        Console.WriteLine(item.Title);
    }

示例代碼2:視圖中的查詢

---建立視圖,查詢沒有分配角色的菜單
create view view_NoRole
as 
select * from Sys_Navigation
where NavID not in (
select distinct  NavID   from Sys_Role_Nav 
)
//查詢視圖
    string sql2 = "select * from view_NoRole";
    List<SysNavigation> roleList = _Context.SysNavigation.FromSql(sql2).ToList();
    foreach (var item in roleList)
    {
        Console.WriteLine(item.Title);
    }

2.ExecuteSqlCommand,執行Sql操做處理

QLLB_SWXContext _Context = new QLLB_SWXContext();
//執行數據操做sql,返回受影響的行數
string sql = "update Sys_Role set SortValue=1 ;";
int count = _Context.Database.ExecuteSqlCommand(sql);
Console.WriteLine(count);

3.自定義SqlQuery,執行列表查詢,在上線文中不存的對象。

示例代碼1:

QLLB_SWXContext _Context = new QLLB_SWXContext();
//特別說明,自定義分裝的不支持 單個值查詢
//不支持object 查詢
//自定義查詢操做 SqlQuery
string sql = "select sum(ViewCount)*1.11 as allCount from Article;";
TempData result = _Context.Database.SqlQuery<TempData>(sql).FirstOrDefault();
Console.WriteLine(result.AllCount);

對象定義

public class TempData
{
    public int CategoryID { get; set; }
    public string Title { get; set; }
    public int ArtCount { get; set; }
    /// <summary>
    /// 求和結果
    /// </summary>
    public decimal AllCount { get; set; }
}

示例代碼2:

執行視圖查詢:

--定義視圖,文章分類和對應分類的文章數量
create view view_CateCount
as
select C.CategoryID,C.Title,  (
select count(*) from Article where CategoryID=C.CategoryID
) as ArtCount  from ArticleCategory C;

C#代碼:

//組合查詢
string sql2 = "select * from view_CateCount;";
List<TempData> tempList = _Context.Database.SqlQuery<TempData>(sql2).ToList();
foreach (var item in tempList)
{
    Console.WriteLine(item.Title);
}

SqlQuery擴展定義:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Reflection;
using System.Text;

namespace QL.Card.Entity
{
    public static class DbContextExtensions
    {
        private static void CombineParams(ref DbCommand command, params object[] parameters)
        {
            if (parameters != null)
            {
                foreach (SqlParameter parameter in parameters)
                {
                    if (!parameter.ParameterName.Contains("@"))
                        parameter.ParameterName = $"@{parameter.ParameterName}";
                    command.Parameters.Add(parameter);
                }
            }
        }

        private static DbCommand CreateCommand(DatabaseFacade facade, string sql, out DbConnection dbConn, params object[] parameters)
        {
            DbConnection conn = facade.GetDbConnection();
            dbConn = conn;
            conn.Open();
            DbCommand cmd = conn.CreateCommand();
            if (facade.IsSqlServer())
            {
                cmd.CommandText = sql;
                CombineParams(ref cmd, parameters);
            }
            return cmd;
        }

        public static DataTable SqlQuery(this DatabaseFacade facade, string sql, params object[] parameters)
        {
            DbCommand cmd = CreateCommand(facade, sql, out DbConnection conn, parameters);
            DbDataReader reader = cmd.ExecuteReader();
            DataTable dt = new DataTable();
            dt.Load(reader);
            reader.Close();
            conn.Close();
            return dt;
        }

        public static IEnumerable<T> SqlQuery<T>(this DatabaseFacade facade, string sql, params object[] parameters) where T : class, new()
        {
            DataTable dt = SqlQuery(facade, sql, parameters);
            return dt.ToEnumerable<T>();
        }

        public static IEnumerable<T> ToEnumerable<T>(this DataTable dt) where T : class, new()
        {
            PropertyInfo[] propertyInfos = typeof(T).GetProperties();
            T[] ts = new T[dt.Rows.Count];
            int i = 0;
            foreach (DataRow row in dt.Rows)
            {
                T t = new T();
                foreach (PropertyInfo p in propertyInfos)
                {
                    if (dt.Columns.IndexOf(p.Name) != -1 && row[p.Name] != DBNull.Value)
                        p.SetValue(t, row[p.Name], null);
                }
                ts[i] = t;
                i++;
            }
            return ts;
        }
    }
}
View Code

 

 更多:

.NetCore中EFCore的使用整理

.NetCore中EFCore的使用整理(二)-關聯表查詢

 .NetCore中EFCore for MySql整理(三)之Pomelo.EntityFrameworkCore.MySql

相關文章
相關標籤/搜索