亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用 EF Core 執行 RAW SQL 查詢?

如何使用 EF Core 執行 RAW SQL 查詢?

C#
12345678_0001 2022-12-24 12:12:04
基本上我遇到的問題是我想在數據庫中運行一個查詢,它不是我的模型的表示。這是我創建與另一個數據庫的連接的代碼:public static OtherContext GetNewContextGeneric(string connectionString)        {            var builder = new DbContextOptionsBuilder();            builder.UseSqlServer(connectionString);            OtherContext db = new OtherContext(builder.Options);            return db;        }這是我執行查詢的代碼:public List<IQueryble> Query (string connectionString, string query)        {            try            {                using(var contextGeneric = ContextFactory.GetNewContextGeneric(connectionString))                {                    //I want something like this                    return contextGeneric.Query(query).ToList();                }            }            catch(System.Data.SqlClient.SqlException ex)            {                throw new SQLIncorrectException(ex);            }            catch(System.InvalidOperationException ex)            {                throw new NotImplementedException();            }           }有人可以幫我嗎?
查看完整描述

5 回答

?
繁星淼淼

TA貢獻1775條經驗 獲得超11個贊

您可以使用DbDataReader:


using (var command = context.Database.GetDbConnection().CreateCommand())

{

    command.CommandText = "SELECT * From Make";

    context.Database.OpenConnection();

    using (var reader = command.ExecuteReader())

    {

        // Do something with result

        reader.Read(); // Read first row

        var firstColumnObject = reader.GetValue(0);

        var secondColumnObject = reader.GetValue(1);


        reader.Read(); // Read second row

        firstColumnObject = reader.GetValue(0);

        secondColumnObject = reader.GetValue(1);

    }

}

在這里您可以了解更多如何從DbDataReader.

或者,您可以使用FromSql()方法,但這僅適用于DbSet某些實體的預定義,這不是您想要的解決方案。


查看完整回答
反對 回復 2022-12-24
?
catspeake

TA貢獻1111條經驗 獲得超0個贊

在你說的問題中:

基本上我遇到的問題是我想在數據庫中運行一個查詢,它不是我的模型的表示。

然后在評論中添加:

因為我不知道數據庫是如何創建的,所以我不知道數據庫中有哪些表我想插入sql查詢

好吧,如果您不知道數據庫,那么您就不能使用 Entity Framework,因為它要求您對要連接的數據庫有詳細的了解。
為此,您應該使用普通的 ADO.NET(如果您想將結果映射回已知類,則可以使用Dapper )。


查看完整回答
反對 回復 2022-12-24
?
鴻蒙傳說

TA貢獻1865條經驗 獲得超7個贊

您仍然可以使用 EF Core 實現外部數據庫的用例,無需求助于 ADO.Net,此解決方案基于@ErikEj 的 EF Core 通用解決方案。(請注意,EF Core 3 的一些函數和命名空間發生了變化,因此保留在 .Net 5+ 中,但仍然可以應用相同的通用概念)


public static IList<T> Query<T>(string connectionString, string query, params object[] parameters) where T : class

{

    try

    {

        using (var contextGeneric = new ContextForQuery<T>(connectionString))

        {

            return contextGeneric.Query<T>().FromSql(query, parameters).ToList();

        }

    }

    catch (System.Data.SqlClient.SqlException ex)

    {

        throw new SQLIncorrectException(ex);

    }

    catch (System.InvalidOperationException ex)

    {

        throw new NotImplementedException();

    }

}


private class ContextForQuery<T> : DbContext where T : class

{

    private readonly string connectionString;


    public ContextForQuery(string connectionString)

    {

        this.connectionString = connectionString;

    }


    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)

    {

        optionsBuilder.UseSqlServer(connectionString, options => options.EnableRetryOnFailure());


        base.OnConfiguring(optionsBuilder);

    }


    protected override void OnModelCreating(ModelBuilder modelBuilder)

    {

        modelBuilder.Entity<T>().HasNoKey();

        base.OnModelCreating(modelBuilder);

    }

}

那么 this 的使用需要一個具體的類型定義,添加對匿名類型的支持需要付出更多的努力,但是為此創建一個具體的類型并不是一件壞事,這里的重點是讓你嘗試更多的聲明式代碼風格因為它們增強了代碼的可讀性和檢查性,并提供文檔和其他擴展配置,如相關實體。


public class NamedObject

{

    public int Id { get; set; }

    public string Name { get; set; }

}


...


var connectionString = "Insert your connection string here...";

var data = Query<NamedObject>(connectionString, "SELECT TOP 10 Id, FullName as Name FROM Employee");

foreach (var emp in data)

{

    Console.WriteLine(emp.Name);

}

背景

在 EF 6(.Net Framework)中,我們可以DbContext.Database.FromSQL<T>()用來執行將自動映射到指定類型的T. 此功能未在 EF Core 中復制,因為結果FromSQL與 EF 的其余部分不一致,結果是一次使用IEnumerable<T>。您無法進一步將此查詢組合到Include()相關實體,也無法向基礎查詢添加過濾器。

在 EF Core to Execute Raw SQL中,您想要返回的類型T需要在 DbContext 中定義為DbSet<T>. 這個集合根本不需要映射到數據庫中的表,事實上,自從 EF Core 2.1 我們不需要為此類型指定,它只是一種預定義預期結構而不是執行的機制按需臨時請求,它為您提供與舊版相同的功能,FromSQL但還允許您定義一組豐富的導航屬性,以便在使用 LINQ to SQL 管道插入RawSQL后進一步組合查詢。

一旦在上下文中定義了類型,您只需調用DbSet<T>.FromSqlRaw(). 不同之處在于,現在我們有一個IQueryable<T>可以用來進一步組合以包含相關實體或應用將在數據庫中評估的過濾器。

此響應中發布的解決方案不允許組合,但按預期順序使用 EF 運行時來提供與原始 EF 6 實現相同的行為。

在最新版本的 EF Core 中,以及現在在 .Net 5+ 中,需要應用以下細微變化:

  • 核心2.1:return contextGeneric.Query<T>().FromSql(query, parameters).ToList();

  • 核心 3+:return contextGeneric.Set<T>().FromSqlRaw(query, parameters).ToList();


查看完整回答
反對 回復 2022-12-24
?
江戶川亂折騰

TA貢獻1851條經驗 獲得超5個贊

您可以使用context.Database.ExecuteSqlRaw("select 1")

不要忘記導入正確的命名空間:using Microsoft.EntityFrameworkCore;


查看完整回答
反對 回復 2022-12-24
?
嚕嚕噠

TA貢獻1784條經驗 獲得超7個贊

它是這樣工作的:


private void SqlCommand (string connectionString, string query)

        {

            using (SqlConnection connection = new SqlConnection(connectionString))

            {

                SqlCommand command = new SqlCommand(query, connection);

                connection.Open();

                SqlDataReader reader = command.ExecuteReader();

                try

                {

                    while (reader.Read())

                    {

                        var a = reader[0];

                    }

                }

                finally

                {

                    // Always call Close when done reading.

                    reader.Close();

                }

            }

        }

要么


using (var connection = ContextFactory.GetNewContextGeneric(connectionString).Database.GetDbConnection())

                {

                    connection.Open();

                    DbCommand command = connection.CreateCommand();

                    command.CommandText = query;


                    using (var reader = command.ExecuteReader())

                    {

                        // Do something with result

                        reader.Read(); // Read first row

                        var firstColumnObject = reader.GetValue(0);

                        /*var secondColumnObject = reader.GetValue(1);


                        reader.Read(); // Read second row

                        firstColumnObject = reader.GetValue(0);

                        secondColumnObject = reader.GetValue(1);*/

                        connection.Close();

                        return firstColumnObject.ToString();

                    }

                }


查看完整回答
反對 回復 2022-12-24
  • 5 回答
  • 0 關注
  • 246 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號