簡體   English   中英

在ObjectDataSource的靜態方法中使用實體框架上下文

[英]Using an Entity Framework Context in static methods for an ObjectDataSource

我有一個現有項目,我想在其中使用ObjectDataSource處理大型數據集,該數據集分頁顯示DevExpress網格的結果。

代碼示例如下所示。

我在ObjectDataSource所需的靜態方法中使用Entity Framework上下文時遇到麻煩。

我的問題是我得到了這個異常:

System.ObjectDisposedException:ObjectContext實例已被處置,不能再用於需要連接的操作。

有誰知道我可以如何更改以下內容以支持將Entities實例從Page傳遞到靜態方法?

這是ObjectDataSource的示例

        <dx:ASPxGridView ID="DefinedReportGrid" runat="server" EnableTheming="True" Theme="Office2010Blue" EnableViewState="False" 
            ClientInstanceName="DefinedReportGrid" DataSourceForceStandardPaging="True" DataSourceID="ReportDataSource">
            <SettingsPager PageSize="30"></SettingsPager>
        </dx:ASPxGridView>

        <asp:ObjectDataSource ID="ReportDataSource" runat="server" EnablePaging="True" 
            StartRowIndexParameterName="startRecord" MaximumRowsParameterName="maxRecords" SelectCountMethod="GetPageCount" SelectMethod="GetData" 
    TypeName="ReportService">
        </asp:ObjectDataSource>

這是我的帶有靜態方法的服務類,然后可以由ObjectDataSource

 public class ReportService
    {
        [DataObjectMethod(DataObjectMethodType.Select, true)]
        public static DataTable GetData(int startRecord, int maxRecords)
        {
        // Use EF DbContent and LINQ Query to fetch paged data, and return a DataTable
        // The data is PIVOTED in the code before returning it as a DataTable

            return outputTable;

        }

        public static List<int> GetWeeks()
        {
        // This also requires use of the EF DbContent
        ...
        }

        public static int GetPageCount()
        {
        // This also requires use of the EF DbContent
        // Used to count the full data for applying the correct total Page Count
        ...
        }
    }

這是Web表單頁面的背后代碼

    public partial class DefinedReport : System.Web.UI.Page
    {
        private Entities _modelContext = ((Global)HttpContext.Current.ApplicationInstance).Entities;

        protected void Page_Init(object sender, EventArgs e)
        {
             ...
        }

        protected void Page_Load(object sender, EventArgs e)
        {
             ...
        }

    }

這是全局代碼,其中在請求的開始和結束處設置了Entities上下文。

    public class Global : HttpApplication
    {
        public Entities Entities { get; set; }

    ...

        private void Application_BeginRequest(object sender, EventArgs e)
        {
            Entities = new Entities();
        }

        private void Application_EndRequest(object sender, EventArgs e)
        {
            if (Entities != null)
            {
                Entities.Dispose();
            }
        }
    }

當有人在帶有靜態/共享方法的VB.Net Webforms應用程序中大量使用DevX網格來封裝各種數據訪問邏輯時,另一種方法是跳過在ASPX中創建ObjectDataSource ,而是在ASPX中設置網格的DataSourceID 。代碼隱藏的Page_Load。 我建立了更易於管理和可預測的方式。

這是想法:

Private Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
    Using eFContext As New ApplicationEntities()
        Dim requestedTransactionId As Guid = GetAndCheckQueryStringValueGuid("TransactionId")
        Dim requestedTransaction As Transaction = Transaction.GetAndConfirm(eFContext, requestedTransactionId)

        Dim requestedCustomers As IQueryable(Of Object) =
            Customer.GetCustomersForCustomersGrid(eFContext, requestedTransaction)

        CustomersGridView.DataSource = requestedCustomers
        CustomersGridView.DataBind()
End Sub

我還為Page_Load中的每個請求創建了一個新的EF上下文-我沒有發現與此相關的性能成為問題,它使查找問題的難度提高了10倍。 您可能要考慮這一點,至少要開始使用。 過去我曾見過其他人建議將您的上下文置於會話狀態,並在需要時從那里獲取它,但這感覺可能會導致各種難以追蹤的弊端,因此我從來沒有足夠大膽地去做。嘗試使這項工作。

作為旁注,如果您遵循我的建議:如果ASPxGridView的初始加載正常,但是在.Includes頁移動,對列進行排序等操作時出現錯誤,則可能需要使用.Includes來顯示相關實體在您的網格中。

此后,我找到了以下示例: http : //www.asp.net/web-forms/tutorials/continuing-with-ef/using-the-entity-framework-and-the-objectdatasource-control,-part-1-入門

這使我意識到, ReportService類上的方法不需要是靜態的即可起作用,這首先是我的主要問題。.我對ObjectDataSource經驗不足,並且正在關注以下示例DevExpress從此處提供: http : //www.devexpress.com/Support/Center/Example/Details/E2672

因此,現在可以在該類的范圍內創建一個新的EF ObjectContext ,然后在處置該類時將其處置,這似乎對我有用。

如下圖所示:

public class ReportService : IDisposable
{
    private bool disposedValue = false;
    private Entities _modelContext = new Entities();

    public DataTable GetData(int startRecord, int maxRecords)
    {
    ...
    // use _modelContext and process the data
        return outputTable;

    }

    public List<int> GetWeeks()
    {
    ...
    // use _modelContext and process the data
    }

    public int GetPageCount()
    {
    ...
    // use _modelContext and process the data
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!this.disposedValue)
        {
            if (disposing)
            {
                _modelContext.Dispose();
            }
        }
        this.disposedValue = true;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM