簡體   English   中英

實體框架模型可以傳遞一個 SQL 腳本來針對數據庫運行嗎

[英]Can Entity Framework model be passed a SQL script to be run against the database

是否可以將 SQL 腳本傳遞給實體框架必須針對我的模型運行它的某些方法? 例如相當於:

context.ExecuteStoreCommand(<tsql script path>); 

背景:我想要一種在單元測試期間重置數據庫的方法,並且調用運行 EF 生成的 TSQL 腳本(來自從模型生成數據庫)似乎是實現此目的的一種方法。

我有一些簡單的代碼可以像這樣觸發 sql:

if (!_context.CableSweepDebug.Any(rec => /* CHECK TO SEE IF SQL ALREADY RUN */ ))
{
    var sql = System.IO.File.ReadAllText("SqlScript.sql");
    _context.Database.ExecuteSqlCommand(sql);
}

我找到了一個簡單的方法:

  1. 將您的 SQL 腳本放入字符串變量中:

     string result = ""; using (Stream stream = assembly.GetManifestResourceStream(resourceName)) { using (StreamReader reader = new StreamReader(stream)) { result = reader.ReadToEnd(); } }
  2. 接下來,使用 GO 作為分隔符拆分字符串:

     string[] commands = result.Split(new string[] { "GO" }, StringSplitOptions.RemoveEmptyEntries);
  3. 最后,使用上下文中的數據庫連接(包含來自https://stackoverflow.com/a/1579220 的代碼)使用完全相同的順序執行每個命令:

     YourContext context = new YourContext(); //Instance new Context DbConnection conn = context.Database.Connection; // Get Database connection ConnectionState initialState = conn.State; // Get Initial connection state try { if (initialState != ConnectionState.Open) conn.Open(); // open connection if not already open using (DbCommand cmd = conn.CreateCommand()) { // Iterate the string array and execute each one. foreach (string thisCommand in commands) { cmd.CommandText = thisCommand; cmd.ExecuteNonQuery(); } } } finally { if (initialState != ConnectionState.Open) conn.Close(); // only close connection if not initially open }

這就是我讓它工作的方式。 希望能幫助到你!

基於 Juanu 的回答,這里是一個適用於 Entity Frame Core 5 的完整解決方案。

在運行測試之前,我使用它來設置數據庫。

    private void SetupTestData()
    {
        var sql = System.IO.File.ReadAllText("SetupEntities.sql");
        string[] commands = sql.Split(new string[] { "GO" }, StringSplitOptions.RemoveEmptyEntries);
        DbConnection conn = _dbContext.Database.GetDbConnection(); // Get Database connection
        var initialConnectionState = conn.State;
        try
        {
            if (initialConnectionState != ConnectionState.Open)
                conn.Open();  // open connection if not already open

            using (DbCommand cmd = conn.CreateCommand())
            {
                // Iterate the string array and execute each one.
                foreach (string thisCommand in commands)
                {
                    cmd.CommandText = thisCommand;
                    cmd.ExecuteNonQuery();
                }
            }
        }
        finally
        {
            if (initialConnectionState != ConnectionState.Open)
                conn.Close(); // only close connection if not initially open
        }
    }

保持簡單

using (var context = new MyDBEntities())
{
    var m = context.ExecuteStoreQuery<MyDataObject>("Select * from Person", string.Empty);
    //Do anything you want to do with 
    MessageBox.Show(m.Count().ToString());
}

不敢相信沒有人回答這個問題。 我現在正在努力解決這個問題。 我想你可以做到這一點的一種方法是將腳本讀入一個字符串,然后在其上執行storecommand。 我想弄清楚的是,這有什么限制。 是否允許除 GO 之外的所有 TSQL 語句? 或者這是你最好使用 sqlcmd.exe 運行的東西。 這是我找到的最佳解決方案 - 使用 SMO 運行腳本:

http://social.msdn.microsoft.com/Forums/en/sqlsmoanddmo/thread/44835d6f-6bca-4374-93e2-3a0d81280781

為什么不簡單地將 SqlConnection 作為一個簡單的 ADO.NET 連接來在測試環境中針對您的數據庫執行 SQL。 因為將有很少和簡單的 SQL 語句,並且您不會在開發場所之外的任何地方部署或導出您的測試。 我認為沒有必要通過實體框架來做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM