0

私はこのエラーに関連する答えの多くを読みました、そして私はまた私の質問に近いいくつかの答えを得ました、しかし私はここで私が間違っていることを追跡することができません

クラスジェネリックリポジトリがあります

public abstract class GenericRepository<TC,T>:IGenericRepository<T> where T:class where TC:ObjectContext , new()
{
    private TC _entities = new TC();
    public TC Context
    {

        get { return _entities; }
        set { _entities = value; }
    }
    public virtual IQueryable<T> GetAll()
    {

        IQueryable<T> query = _entities.CreateObjectSet<T>();
        return query;
    }
    public virtual void Add(T entity)
    {
        _entities.CreateObjectSet<T>().AddObject(entity);
    }
    // save,update,insert etc etc
}

私のリポジトリクラスは

public class MenuRepository:GenericRepository<mbsEntities,menu>,IMenu
{
    public menu GetMenu(int id)
    {
        return GetAll().FirstOrDefault(x => x.menu_id == id);
    }
    public bool CreateMenu(string menuName, int menuLevel, string menuUrl, int menuParent,int menuPosition,int roleId)
    {
        if(!Profile.IsInRole(Enums.Enumerations.Roles.Admin))
            return false;
        var menu = new menu()
                       {
                           menu_name = menuName,
                           menu_level=menuLevel,
                           menu_url = menuUrl,
                           menu_parent = menuParent,
                           menu_position = menuPosition,

                       };
        var roleRepository = new RoleRepository();
        var role = roleRepository.GetAll().FirstOrDefault(x => x.id == roleId);
        menu.traffic_role.Add(role);
        try
        {
            Add(menu);      // here im getting error “An entity object cannot be referenced by multiple instances of IEntityChangeTracker”
            Save();
        }
        catch (Exception)
        {
            return false;
        }
        return true;
    }
}

私は間違った方法で行っていますか?

4

1 に答える 1

1

'MenuRepository'とRoleRepositoryリポジトリは異なるコンテキストを使用します。クエリを実行する前に、のコンテキストRoleRepositoryを使用するようにのコンテキストを設定します。MenuRepository

public class MenuRepository:GenericRepository<mbsEntities,menu>,IMenu
{
    public menu GetMenu(int id)
    {
        return GetAll().FirstOrDefault(x => x.menu_id == id);
    }
    public bool CreateMenu(string menuName, int menuLevel, string menuUrl, int menuParent,int menuPosition,int roleId)
    {
        if(!Profile.IsInRole(Enums.Enumerations.Roles.Admin))
            return false;
        var menu = new menu()
                       {
                           menu_name = menuName,
                           menu_level=menuLevel,
                           menu_url = menuUrl,
                           menu_parent = menuParent,
                           menu_position = menuPosition,

                       };
        var roleRepository = new RoleRepository();

        roleRepository.Context = Context;

        var role = roleRepository.GetAll().FirstOrDefault(x => x.id == roleId);
        menu.traffic_role.Add(role);
        try
        {
            Add(menu);      // here im getting error “An entity object cannot be referenced by multiple instances of IEntityChangeTracker”
            Save();
        }
        catch (Exception)
        {
            return false;
        }
        return true;
    }
}

デザインは、リークのある抽象化に悩まされています。リポジトリのコンストラクタインジェクションを使用して、コンテキストをインジェクトします。誤って複数のコンテキストを作成することをある程度防ぐことができます。依存性注入フレームワークを使用し、メソッド内でインスタンス化せずに依存性を明示的にします。

public abstract class GenericRepository<TC,T>:IGenericRepository<T> where T:class where TC:ObjectContext , new()
{
    protected GenericRepository(TC context)
    {
       Context = context;
    }

    public TC Context
    {
        get; protected set;
    }

}
于 2012-04-23T06:51:01.530 に答える