【问题标题】:The ObjectContext instance has been disposed and can no longer be used for operations that require a connection errorObjectContext 实例已被释放,不能再用于需要连接错误的操作
【发布时间】:2016-08-16 21:08:35
【问题描述】:

我一直在使用带有 Visual Studio 2012 的实体框架(数据库优先)的项目。它是 ASP.NET MVC 项目(C#),剃刀。在视图中我有一个剑道网格:

@(Html.Kendo().Grid<RunSummary>()
          .Name("CheckedPatients")                    
          .DataSource(datasource => datasource                
                .Ajax().PageSize(25)        
                .ServerOperation(false)                           
                .Sort(sort => sort.Add("TimeOn").Descending())
                .Read(read => read.Action("GetRunSummaries", "PatientReport")))              

          .Columns(columns =>
              {
                  columns.Bound(c => c.UniqueId).Title(ELSORegistry.Resources.Views.Home.HomeStrings.UniqueId)
                      .ClientTemplate("<input type='checkbox'  class='primaryBox'  id='#= UniqueId #' value='#= UniqueId #'>#= UniqueId #</input>");                        
                  columns.Bound(c => c.RunNo).Title(SharedStrings.Run);
                  columns.Bound(c => c.Birthdate).Title(SharedStrings.Birthdate).Format("{0:g}").Filterable(true);

                  columns.Bound(c => c.customAge).Title(SharedStrings.Age)
                         .Filterable(
                             filterable => filterable
                                 .UI("AgeFilter")
                                 .Extra(false)
                                 .Operators(operators => operators
                                     .ForString(str => str.Clear().IsEqualTo("Is equal to"))
                                     )

                       );

                  columns.Bound(c => c.TimeOn).Title(PatientStrings.DateOn)
                      .Format("{0:g}")
                      .Filterable(true);
                  columns.Bound(c => c.TimeOff).Title(PatientStrings.DateOff)
                      .Format("{0:g}")
                      .Filterable(true);

                  columns.Bound(c => c.DischargedAlive).Title(PatientStrings.DischargedAlive).Filterable(true);//.ClientTemplate("#= DischargedAlive ? 'Yes' : 'No' #");
                  columns.Bound(c => c.ShowSubmitted).Title(PatientStrings.Submitted).Filterable(true);//.ClientTemplate("#= ShowSubmitted ? 'Yes' : 'No' #");
                  columns.Bound(c => c.SupportTypeEnum).Title(PatientStrings.SupportType).Filterable(true);//.ClientTemplate("#= SupportType ? 'Yes' : 'No' #");
              }
          )
          .Pageable(p => p.PageSizes(new[] {10, 25, 50, 100}))
          .Sortable()
          .Filterable( )
          .Events( e => e.FilterMenuInit("FilterMenuFuncWithAge") ) // apply x [closing box] on pop up filter box
          )

作为 Kendo Grid 的来源,我使用了存储过程:

CREATE PROCEDURE [dbo].[IGD_spPatientListReportFillGrid]
(@CenterId uniqueidentifier)


AS
BEGIN
 SET NOCOUNT ON

-- DECLARE @start DATETIME, @end DATETIME;
-- SET @start = GETDATE();


  SELECT R.RunId, R.submittedDate, R.CompletedBy, R.isRunLocked, R.LockDate, P.isPatientLocked, DATEDIFF(DAY, ISNULL

(R.submittedDate, GETDATE()), GETDATE()) 
                         AS DaysDiff, CP.CenterId, P.PatientId,
                         P.UniqueId,
                         R.RunNo,
                         R.SupportType,
                         CAST(P.Birthdate AS DATETIME) AS Birthdate,
                         P.Sex, P.Race, 
                         R.Discontinuation,
                         R.DischargedAlive,
                         CAST(R.AdmitDate AS DATETIME) AS AdmitDate,YEAR(R.TimeOn) AS Year,
                         CAST(R.TimeOn AS DATETIME) AS TimeOn,
                         CAST(ISNULL(R.TimeOff,
                         (SELECT TOP (1) EndTime
                          FROM ECLS.RunDetails AS RD
                          WHERE (RunId = R.RunId) AND (NOT (EndTime IS NULL))
                          ORDER BY EndTime DESC)) AS DATETIME2) AS TimeOff,

                         CAST(R.DischargeDate AS DATETIME) AS DischargeDate,
                         CAST(R.DeathDate AS DATETIME) AS DeathDate,
                         DATEDIFF(day, CAST(P.Birthdate AS DATETIME), CAST(R.TimeOn AS DATETIME)) AS Age,
                         R.CompletedDate,
                          CASE WHEN (R.CompletedBy IS NULL) OR
                         ((R.TimeOn IS NULL) OR
                         (R.TimeOff IS NULL)) OR
                         (R.CompletedBy IS NOT NULL AND ((R.TimeOn IS NULL) OR
                         (R.TimeOff IS NULL))) THEN 'false' ELSE 'true' END AS IsCompleted, 
                         dbo.ELSO_IGD_CalculateAge(DATEDIFF(day, P.Birthdate,R.TimeOn)) AS customAge,
          CASE WHEN (R.CompletedBy IS NULL) OR
                         ((R.TimeOn IS NULL) OR
                         (R.TimeOff IS NULL)) OR
                         (R.CompletedBy IS NOT NULL AND ((R.TimeOn IS NULL) OR
                         (R.TimeOff IS NULL))) THEN 'false' ELSE 'true' END AS ShowSubmitted




  FROM ECLS.Runs AS R INNER JOIN
       Registry.Patients AS P ON R.PatientId = P.PatientId INNER JOIN
       Registry.CenterPatients CP ON P.PatientId = CP.PatientId
  WHERE CP.CenterId = @CenterId 
  ORDER BY  R.TimeOn;           


END;

我使用“从数据库更新模型”导入了存储过程,目标类型是实体“RunSummary”(Kendo Grid 使用它作为模型)。与模型通信的过程是:

public List<RunSummary> GetRunSummariesForPatientReportGrid(Guid? centerId)
        {
            using (var context = new ELSORegistryEntities())
            {
                return context.IGD_spPatientListReportFillGrid(centerId).ToList<RunSummary>();
            }
        }

控制器中的代码是:

public JsonResult GetRunSummaries([ELSORegistry.Helpers.CustomDataSourceRequest] DataSourceRequest request)
        {
            var center = Session["Center"] as Center;
            var centerId = center != null && center.CenterNo != 0 ? center.CenterId : (Guid?)null;

            List<RunSummary> myList = new Repository().GetRunSummariesForPatientReportGrid(centerId);


            return Json(myList.ToDataSourceResult(request), JsonRequestBehavior.AllowGet);

        }

我的问题是剑道网格没有显示任何内容,它是空的。在浏览器的控制台中,我发现错误:“ObjectContext 实例已被释放,不能再用于需要连接的操作”。 (我想提一下,ShowSubmitted 字段是在 RunSummary 的模型扩展中实现的,如:

public bool ShowSubmitted
        {
            get
            {
                return this.LookForSubmitted();
            }
        }  
private bool LookForSubmitted()
        {
            bool retVal = false;

            retVal = (new Repository()).GetSubmitted(this.RunId);

            return retVal;

        }

public bool GetSubmitted(Guid? runId = null)
        {

            using (var context = new ELSORegistryEntities())
            {
                context.Configuration.ProxyCreationEnabled = false;
                RunSummary run = context.RunSummaries.FirstOrDefault<RunSummary>(p => p.RunId == runId);

                bool submitted = false;
                if (run.IsCompleted == "true")
                    {
                        submitted = true;
                    }
                    else
                    {
                        submitted = false;
                    }

                return submitted;
            }

        }

任何想法,如何解决这个问题?预先感谢您的任何帮助。

【问题讨论】:

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


    【解决方案1】:

    尝试通过将以下代码 sn-p 添加到 DbContext 类来禁用 lazy loading。默认情况下,Entity Framework 延迟加载数据,这意味着数据在被请求之前不会加载。

    public AlenanDBEntities(): base("name=AlenanDBEntities")
    {
        this.Configuration.LazyLoadingEnabled = false;
    }
    

    如果您不想为所有实体禁用延迟加载,可以通过使用 virtual 关键字声明属性来启用eagerly loading。不知道你的实体是什么样子的,你会添加这样的东西

    public class Run
    {
         public virtual List<RunSummary> RunSummaries { get; set; }
    }
    

    【讨论】:

    • 感谢您的关注和帮助。我发现问题在于 RunSummary 对象具有虚拟属性 PatientSummary,并尝试获取它(存储过程返回数据集的地方是不可能的)。 [System.Web.Script.Serialization.ScriptIgnore] public virtual PatientSummary PatientSummary { get; set; }如何避免实体框架中的对象PatientSummary?提前感谢您的帮助。
    猜你喜欢
    • 2013-07-15
    • 2012-07-17
    • 1970-01-01
    相关资源
    最近更新 更多