EF4.0 - Есть ли способ увидеть, какие объекты подключены к какому ObjectContext во время отладки? - PullRequest
0 голосов
/ 03 июня 2011

Это продолжение моей проблемы здесь .

Я пытаюсь использовать решение , которое Джули Лерман дала мне несколько месяцев назад . В настоящее время я использую следующее для создания новой сущности Game, предварительно прикрепленной к моему ObjectContext:

Game game = _gameRepository.GetGame(formData.GameID);
AutoMapper.Mapper.Map<AdminGameEditModel, Game>(formData, game);

В репозитории я пытаюсь подключить Игру к OC с ее состоянием, установленным в «Добавлено», как она предложила, выполнив следующее:

public Game GetGame(int id)
{
    if (id > 0)
    {
        return _siteDB.Games.Include("Genre").Include("Platforms").SingleOrDefault(g => g.GameID == id);
    }
    else
    {
        Game game = _siteDB.Games.CreateObject();
        _siteDB.Games.AddObject(game);
        return game;
    }
}

Теперь, для ясности, вот конструктор моего контроллера в полном объеме:

public AdminController(IArticleRepository articleRepository, IGameRepository gameRepository, INewsRepository newsRepository)
{
    _articleRepository = articleRepository;
    _gameRepository    = gameRepository;
    _newsRepository    = newsRepository;

    Mapper.CreateMap<AdminGameEditModel, Game>()
        .BeforeMap((s, d) =>
        {
            if (d.Platforms.Count > 0)
            {
                Platform[] existing = d.Platforms.ToArray();

                foreach (var plat in existing)
                {
                    d.Platforms.Remove(plat);
                }
            }

            foreach (var platId in s.PlatformIDs)
            {
                Platform newPlat = _gameRepository.GetPlatform(platId);
                d.Platforms.Add(newPlat);
            }
        })
        .ForMember(dest => dest.BoxArtPath, opt => opt.Ignore())
        .ForMember(dest => dest.IndexImagePath, opt => opt.Ignore())
        .ForMember(dest => dest.Cons, opt => opt.MapFrom(src => String.Join("|", src.Cons)))
        .ForMember(dest => dest.Pros, opt => opt.MapFrom(src => String.Join("|", src.Pros)))
        .ForMember(dest => dest.LastModified, opt => opt.UseValue(DateTime.Now))
        .ForMember(dest => dest.Platforms, opt => opt.Ignore());
}

Как видите, _gameRepository должен быть таким же, так как он создан при построении контроллера. Это, в свою очередь, означает, что OC _gameRepository должен быть одинаковым как для игры, так и для платформ. Тем не менее, в этом случае я все еще получаю исключение, которое гласит:

Невозможно определить отношения между двумя объектами, поскольку они присоединены к разным объектам ObjectContext.

Определенно происходит что-то странное, поэтому я хочу знать, смогу ли я действительно проследить, к какому ObjectContext сущности прикреплены. Все они должны быть присоединены к одному и тому же OC, но исключение требует иного.

Может быть, это как-то связано со мной, используя Ninject (версия vanilla, , а не версия с учетом MVC), чтобы внедрить репозитории в контроллер. Какова бы ни была проблема, это вряд ли кажется очевидным. Любая помощь будет очень признательна.

РЕДАКТИРОВАТЬ: ObjectContext репозитория:

public class HGGameRepository : IGameRepository
{
    private HGEntities _siteDB = new HGEntities();

    // rest of class code
}

Ninject bindings:

private class HandiGamerServices : NinjectModule
{
    public override void Load()
    {
        Bind<IArticleRepository>().To<HGArticleRepository>().InRequestScope();
        Bind<IGameRepository>().To<HGGameRepository>().InRequestScope();
        Bind<INewsRepository>().To<HGNewsRepository>().InRequestScope();
        Bind<ErrorController>().ToSelf().InRequestScope();
    }
}

Ответы [ 2 ]

2 голосов
/ 04 июня 2011

Вы можете запросить ObjectContext, если у него есть ссылка на определенный объект:

ObjectStateEntry ose;
bool isInContext = someContext.ObjectStateManager.TryGetObjectStateEntry(someObject, out ose);
1 голос
/ 03 июня 2011

Проблемная часть заключается в следующем:

public class HGGameRepository : IGameRepository
{
    private HGEntities _siteDB = new HGEntities();

    // rest of class code
}

Я полагаю, что все ваши репозитории при создании создают свои собственные новые контексты.Вместо этого вы должны использовать конструктор инъекций

public class HGGameRepository : IGameRepository
{
    private HGEntities _siteDB;

    public HGGameRepository(HGEntities entities)
    {
          _siteDB= entities
    }
}

Затем в ваш модуль Ninject включите это

Bind<HGEntities>().ToSelf().InRequestScope();

Таким образом, ваши репозитории будут использовать тот же контекст.

...