【问题标题】:Can Entity Framework model be passed a SQL script to be run against the database实体框架模型是否可以传递一个 SQL 脚本以针对数据库运行
【发布时间】:2010-05-29 21:46:26
【问题描述】:

是否可以将 SQL 脚本传递给 Entity Framework 必须针对我的模型运行它的某个方法?例如相当于:

context.ExecuteStoreCommand(<tsql script path>); 

背景:我想要一种在单元测试期间重置数据库的方法,并且调用运行 EF 生成的 TSQL 脚本(来自从模型生成数据库)似乎是实现此目的的一种方法。

【问题讨论】:

  • 恕我直言:在单元测试期间不要连接到数据库。问题解决了。
  • 如果我使用术语集成而不是单元会怎样

标签: .net sql tsql entity-framework


【解决方案1】:

我有一些像这样触发 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);
}

【讨论】:

  • 这很好用,除非您的 SQL 脚本包含 GO 语句或 cmets,否则会出现语法错误。
【解决方案2】:

我找到了一个简单的方法:

  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
    }
    

这就是我让它工作的方式。希望对您有所帮助!

【讨论】:

    【解决方案3】:

    根据 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
            }
        }
    

    【讨论】:

      【解决方案4】:

      不敢相信没有人回答这个问题。我现在正试图弄清楚这一点。我想你可以做到这一点的一种方法是将脚本读入一个字符串,然后对其执行storecommand。我想弄清楚的是这有什么限制。是否允许除 GO 之外的所有 TSQL 语句?或者这是你最好使用 sqlcmd.exe 运行的东西。这是我找到的最佳解决方案 - 使用 SMO 运行脚本:

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

      【讨论】:

        【解决方案5】:

        您为什么不简单地将 SqlConnection 作为一个简单的 ADO.NET 连接来在测试环境中对您的数据库执行 SQL。因为将有非常少且简单的 SQL 语句,并且您不会在开发场所之外的任何地方部署或导出测试。我认为没有必要通过实体框架来做。

        【讨论】:

          【解决方案6】:

          保持很简单

          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());
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-11-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-07-08
            相关资源
            最近更新 更多