Я использую EF6 для запроса к базе данных. Пользователь может настроить временную таблицу и запросить данные из временной таблицы. Я использую
DataTable result = context.Query(queryStatement);
чтобы получить результат, и он работал нормально.
Теперь запрос необходим среди серьезных других команд sql, и необходима транзакция. Итак, у меня есть
public static DataTable GetData()
{
using (MyDbContext context = new MyDbContext())
using (DbContextTransaction tran = context.Database.BeginTransaction())
{
try
{
int rowAffected = context.Database.ExecuteSqlCommand(
"UPDATE [MyDb].dbo.[TableLocks] SET RefCount = RefCount + 1 WHERE TableName = 'TESTTABLE1'");
if (rowAffected != 1)
throw new Exception("Cannot find 'TestTable1'");
//The following line will raise an exception
DataTable result = context.Query("SELECT TOP 100 * FROM [MyDb].dbo.[TestTable1]");
//This line will work if I change it to
//context.Database.ExecuteSqlCommand("SELECT TOP 100 * FROM [MyDb].dbo.[TestTable1]");
//but I don't know how to get the result out of it.
context.Database.ExecuteSqlCommand(
"UPDATE [MyDb].dbo.[TableLocks] SET RefCount = RefCount - 1 WHERE TableName = 'TestTable1'");
tran.Commit();
return result;
}
catch (Exception ex)
{
tran.Rollback();
throw (ex);
}
}
}
Но это вызывает исключение при выполнении контекста. Запрос
ExecuteReader requires the command to have a transaction when the connection
assigned to the command is in a pending local transaction. The Transaction
property of the command has not been initialized.
И когда я читаю эту статью: https://docs.microsoft.com/en-us/ef/ef6/saving/transactions
Там написано:
Entity Framework не переносит запросы в транзакции.
Это причина этой проблемы?
Как я могу использовать context.Query()
внутри транзакции?
Что еще я могу использовать?
Я испробовал все другие методы, ни один из них не работает - потому что тип данных возврата не может быть предсказан заранее.
Я только что понял, что метод Query определен в MyDbContext!
public DataTable Query(string sqlQuery)
{
DbProviderFactory dbFactory = DbProviderFactories.GetFactory(Database.Connection);
using (var cmd = dbFactory.CreateCommand())
{
cmd.Connection = Database.Connection;
cmd.CommandType = CommandType.Text;
cmd.CommandText = sqlQuery;
using (DbDataAdapter adapter = dbFactory.CreateDataAdapter())
{
adapter.SelectCommand = cmd;
DataTable dt = new DataTable();
adapter.Fill(dt);
return dt;
}
}
}