Передача LinqDataSource через сессию: «DataContext доступен после удаления». - PullRequest
0 голосов
/ 19 января 2009

Мне нужно передать некоторые результаты из базы данных. Вместо того, чтобы передать весь набор данных или построенный SQL-запрос, я попытался передать настроенный объект LinqDataSource.

На исходной странице я настраиваю свойства объекта LinqDataSource Где и WhereParameters , используя значения, установленные пользователем для элементов управления, отображаемых на странице (окно поиска, поле со списком и т. Д. .). Я передаю объект, чтобы избежать реконфигурации LinqDataSource на странице получателя.

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

Невозможно получить доступ к удаленному объекту.

Имя объекта: «Доступ к DataContext после Dispose.».

На обеих страницах, источника и получателя, объекты LinqDataSource объявлены как:

<asp:LinqDataSource ID="myLinqDS" runat="server" 
    ContextTypeName="MyProject.MyDBNamedpace.MyDataContext" 
    TableName="TheTable"
    OrderBy="field1, field2"
</asp:LinqDataSource>

Чтобы передать объект источника данных, я делаю это:

SetLinqDataSourceWhereAndHisParameters(); //just set Where and WhereParameters
Guid guid = Guid.NewGuid();
Session[guid.ToString()] = myLinqDS;
ScriptManager.RegisterStartupScript(this.Page,
    typeof(Page),
    "Redirect",
    String.Format(@"window.open(""{0}"");",
        this.ResolveClientUrl("~/PageToDisplayTheData.aspx?guid=" +
        System.Web.HttpUtility.UrlEncode(guid.ToString())
    ),
true);

А для извлечения из кода страницы PageToDisplayTheData.aspx:

myLinqDS =
   (LinqDataSource)Session[System.Web.HttpUtility.UrlDecode(Request.QueryString[guid])];
aDataList.DataSource = myLinqDS;
aDataList.DataBind();

Ответы [ 3 ]

2 голосов
/ 20 января 2009

Вы должны , а не хранить DataContext в сеансе (или в любом месте) по следующим причинам:

  • DataContext не является потокобезопасным
  • DataContext разработан как инструмент единицы работы

Если вы запрашиваете коллекцию в DataContext, она внутренне кэшируется, поэтому, когда вы запрашиваете ее, вы не совершаете обратного обращения к базе данных. Но это может привести к стагнации данных, поскольку значения не отражают фактическое состояние базовой базы данных.

0 голосов
/ 19 января 2009

Просто скопировал свойства из одного объекта в другой, и это сработало:

LinqDataSource received=
(LinqDataSource)Session[System.Web.HttpUtility.UrlDecode(Request.QueryString[guid])];

myLinqDS.Where = received.Where;
foreach (Parameter p in received.WhereParameters)
    myLinqDS.WhereParameters.Add(p);

Но я до сих пор не знаю, почему он работал на внутреннем веб-сервере VS2008, но не на главном сервере с IIS.

0 голосов
/ 19 января 2009

Какова ваша цель? Если вы не хотите, чтобы приложение возвращалось в базу данных, вам все равно придется кэшировать весь набор данных. Если вы просто пытаетесь не создавать запрос заново, почему бы не добавить запрос в контекст данных как метод и ссылаться на него отовсюду.

public partial class MyDataContext
{
    public Table<MyTable> OrderedTable()
    {
         return this.TheTable.OrderBy( t => t.field1 )
                             .ThenBy( t => t.field2 );
    }
}
...