导致此错误的原因“由于已经处理了DbContext,因此无法完成操作”

时间:2013-05-07 15:44:38

标签: c# asp.net-mvc entity-framework

1。 我在我的存储库类中有这个方法

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

3 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分:0)

好的,通过使用原始ado.net代码解决了这个问题,所以我只是将find方法从实体框架linq代码更改为原始ado.net数据访问代码。 错误不再发生,如果有人有更好的解决方案使用实体框架,请分享。重写了find方法,代码如下:

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;

        }

答案 2 :(得分:0)

原因是你的LINQ查询是延迟的,换句话说它不会在你的" VariablesRepository"中运行。但只在调用代码中。因此DBContext在执行时已经被处理掉了。您可以通过添加.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();