2013-05-07 4 views
0

1. У меня есть этот метод в моем хранилище классаЧто вызывает эту ошибку «Операция не может быть завершена, поскольку DbContext были захоронены»

public class VariablesRepository : IVariablesRepository 
    { 
     readonly DBContextClass _context = DBContextClass.Current; 
     public Variables Find(string name) 
     { 
      return _context.Variables.FirstOrDefault(c => c.Name.ToLower().Equals(name.ToLower())) ?? new Variables(); 
     } 
    } 

2. У меня также есть статический класс

public class Defaults { 
     private static VariablesRepository _variablesRepository; 
     static Defaults() { 
      _variablesRepository = new VariablesRepository(); 
     } 
    public class MOSScheduleTypes 
    { 
     private static int _tryValue; 

     public static readonly int OneTime = int.TryParse(_variablesRepository.Find("MOSScheduleTypes.OneTime").Value, out _tryValue) 
                 ? _tryValue 
                 : 1; 
    } 
} 

3. Теперь, если я сделать это где-то в коде: например

if(someValue == Defaults.MOSScheduleTypes.OneTime) 
{ 
    //some code here.... 
} 

Я получаю сообщение об ошибке: операция не может быть завершена, потому что DbContext был удален

+0

Где вы инстанцировании '_variablesRepository'? –

+0

MOSScheduleTypes - это класс внутри класса с именем Defaults. Класс Defaults имеет _variablesRepository экземпляр –

+0

Не возражаете ли вы обновить свой вопрос с помощью этой информации? Даже если я не могу помочь, кто-то может найти эту информацию полезной. –

ответ

0

Ok, решить эту проблему с помощью сырого кода ADO.NET, так что я просто изменил способ найти с рамочной сущностью кода Linq в код доступа к данным сырого ado.net. Ошибка больше не возникает, если у кого-то есть лучшее решение, использующее инфраструктуру сущности, поделитесь ею. Метод находкой переписан, код ниже:

public Variables Find(string name) 
     { 
      var objVariable = new Variables(); 

      using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStringValue"].ToString())) 
      { 
       conn.Open(); 

       var sql = @" select top 1 * 
          from SomeTable 
          where Column1 = @Name"; 

       try 
       { 
        var cmd = new SqlCommand(sql, conn); 
        cmd.CommandType = CommandType.Text; 

        cmd.Parameters.Add("@Name", SqlDbType.NVarChar).Value = name; 

        SqlDataReader dr = cmd.ExecuteReader(); 
        if (dr.HasRows) 
        { 
         if (dr.Read()) 
         { 
          objVariable.Column1 = dr["Column1"].ToString(); 
          objVariable.Column2 = dr["Column2"].ToString(); 
         } 
        } 

       } 
       catch (Exception ex) 
       { 
        throw new Exception(ex.Message); 
       } 
      } 

      return objVariable; 

     } 
1

Ошибка вызвана размещением контекста данных. Поскольку вы не указали какой-либо код для утилизации ... ничего, это означает, что есть какой-то код в другом месте, который избавляется от того же контекста данных.

Обратите внимание, что контексты данных рассчитаны на короткое замыкание; это запах кода, чтобы видеть, как вы держитесь за контекст данных, как и для последующего использования, особенно в статической переменной, которая, как представляется, долговечна.

Вместо того, чтобы захватывать текущий контекст данных, как только вы должны захватить его прямо, когда вам это нужно. Поскольку вы не будете хранить контекст данных в качестве поля экземпляра VariablesRepository, этот метод также можно сделать статическим (он не будет иметь данных экземпляра для использования).

public class VariablesRepository : IVariablesRepository 
{ 
    public static Variables Find(string name) 
    { 
     return DBContextClass.Current.Variables.FirstOrDefault(c => c.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase)) ?? new Variables(); 
    } 
} 

public class Defaults 
{ 
    public class MOSScheduleTypes 
    { 
     private static int _tryValue; 

     public static readonly int OneTime = int.TryParse(VariablesRepository.Find("MOSScheduleTypes.OneTime").Value, out _tryValue) 
                 ? _tryValue 
                 : 1; 
    } 
} 
0

Причина этого заключается в том, что ваш запрос LINQ отсрочена, другими словами, он не запускается в вашем «VariablesRepository», но только в коде вызова. Таким образом, DBC-контекст уже удаляется, когда он выполняется. Вы можете заставить его немедленно выполнить путем добавления .ToList() поэтому изменение

return _context.Variables.FirstOrDefault(c => c.Name.ToLower().Equals(name.ToLower())) ?? new Variables(); 

в

return _context.Variables.ToList().FirstOrDefault(c => c.Name.ToLower().Equals(name.ToLower())) ?? new Variables(); 
Смежные вопросы