0

これは、ここでの私の問題の続きです。

JulieLermanが数か月前にくれたソリューションを使おうとしています。現在、以下を使用して、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はコントローラー構築で作成されているため、同じである必要があります。つまり、_gameRepositoryのOCは、ゲームとプラットフォームの両方で同じである必要があります。それでも、その場合でも、次のような例外が発生します。

2つのオブジェクトは異なるObjectContextオブジェクトにアタッチされているため、2つのオブジェクト間の関係を定義することはできません。

何か厄介なことが確実に起こっているので、エンティティが実際に接続されているObjectContextを実際に追跡できるかどうかを知りたいのです。それらはすべて同じOCに接続する必要がありますが、例外はそうではないと主張します。

たぶんそれは、Ninject(MVCに合わせたバージョンではなく、バニラバージョン)を使用してコントローラーにリポジトリーを注入することと関係があります。問題が何であれ、それはほとんど明白ではないようです。どんな助けでも歓迎です。

編集:リポジトリのObjectContext:

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

    // rest of class code
}

バインディングを挿入します:

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();
    }
}
4

2 に答える 2

2

次の方法で、特定のオブジェクトへの参照があるかどうかを ObjectContext に問い合わせることができます。

ObjectStateEntry ose;
bool isInContext = someContext.ObjectStateManager.TryGetObjectStateEntry(someObject, out ose);
于 2011-06-03T21:22:01.290 に答える
1

問題の部分はこれです

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();

このようにして、リポジトリは同じコンテキストを共有します。

于 2011-06-03T01:46:49.087 に答える