开发者

EF4.0 - Is there a way to see what entities are attached to what ObjectContext during debugging?

This is in continuation with my problem here.

I'm trying to use the solution Julie Lerman gave me a few months ago. I'm currently using the following to generate a new Game entity pre-attached to my ObjectContext:

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

In the repository, I try to attach the Game to the OC with its state set to 'Added' like she suggested by doing the following:

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;
    }
}

Now, for clarity's sake, here's my controller's constructor in its entirety:

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.Platf开发者_如何转开发orms.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());
}

As you can see, the _gameRepository should be the same, since its created on controller construction. This, in turn, means that the _gameRepository's OC should be the same for both the Game and Platforms. Yet, with that being the case, I'm still getting an exception which states:

The relationship between the two objects cannot be defined because they are attached to different ObjectContext objects.

Something screwy is definitely going on, which is why I want to know if I can actually trace which ObjectContext the entities are actually attached to. They should all be attached to the same OC, but the exception claims otherwise.

Maybe it has something to do with me using Ninject (the vanilla version, not the MVC tailored version) to inject the repositories in the controller. Whatever the problem is, it hardly seems obvious. Any help would be greatly appreciated.

EDIT: Repository's 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();
    }
}


You can ask the ObjectContext if it has a reference to a certain object by:

ObjectStateEntry ose;
bool isInContext = someContext.ObjectStateManager.TryGetObjectStateEntry(someObject, out ose);


The problematic part is this

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

    // rest of class code
}

I believe all your Repositories create new Contexts of their own when created. Instead of this you should use constructor injection

public class HGGameRepository : IGameRepository
{
    private HGEntities _siteDB;

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

Then in your Ninject module include this

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

This way your repositories will share the same context.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜