Entity Framework - загрузка ссылочных ключей после удаления контекста объекта - PullRequest
1 голос
/ 10 августа 2011

Я использую ASP.Net / WebForms / Entity Model / Framework 3.5

Вот простая структура моего проекта Forms> BLL> DAL (использует модель объекта)

Вот фрагмент моего DAL

public class MyDAL : IDisposable
{
    private MyEntities db;
    public BaseDAL()
    {
        db = new MyEntities();
    }

    public User GetUserByID(int userId)
    {
        try
        {
            IQueryable<User> objUser = null;
            objUser  = from res in db.Users
                          where res.UserId == userId
                          select res;

            return objUser.FirstOrDefault();
        }
        catch
        {
            throw;
        }
    }

    public void Dispose()
    {
        db.Dispose();
    }
}

Я вызываю функцию DAL из моего BLL следующим образом

public class MyBLL
{
    public User GetUserByID(int userId)
    {
        try
        {
            using (MyDAL objMyDAL = new MyDAL())
            {
                return objMyDAL.GetUserByID(userId);
            }
        }
        catch
        {
            throw;
        }
    }
}

Я вызываю DAL через , используя блок , так что событие Dispose MyDAL будет запущено вскоре послеBLL возвращает объект User.Поэтому на этом этапе экземпляр ObjectContext удаляется.

Теперь в моей веб-форме я вызываю эту функцию следующим образом, чтобы получить информацию о пользователе и сведения о группе, которые являются внешним ключом таблицы user_Group в таблице User

    protected void Page_Load(object sender, EventArgs e)
    {
        MyBLL objMyBll = new MyBLL();

        User objUser = objMyBll.GetUserByID(123);
        objUser.User_GroupReference.Load(); // ERROR LINE
        int groupId = objUser.User_Group.Group_Id;
    }

Когда ода появляется в строке objUser.User_GroupReference.Load(); Я получаю это исключение

Экземпляр ObjectContext был удален и больше не может использоваться для операций, требующих подключения.

Как решить эту проблему?Если я не делаю db.Dispose(); в методе утилизации моего DAL, он работает нормально, и никаких исключений не происходит.Но если я не буду располагать там объект db, когда и где мне его расположить?А как получить доступ к ссылочным ключам после удаленного контекста объекта?

1 Ответ

2 голосов
/ 10 августа 2011

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

В вашей архитектуре вы должныиспользуйте Include для явной загрузки всех отношений, которые вам понадобятся в верхних слоях.Если вы хотите использовать ленивую загрузку, ваш контекст должен жить в течение всего периода запроса.В случае веб-форм это может быть обработано, например, в обработчиках событий BeginRequest и EndRequest, где вы создаете контекст в BeginRequest и располагаете его в EndRequest.Контекст будет храниться в HttpContext.Items.Вы должны получить контекст из этой коллекции (вы можете сделать для этого вспомогательный метод) и передать его конструктору BLL, который, в свою очередь, передаст его DAL.Не входите в HttpContext.Items из списка BLL или DAL.

...