Reputation: 3911
i have read many of the answer related to this error and i also got some few answers which are close to my question but im not able to track what i'm doin' wrong here
i have a class generic repository
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
}
and my repository class is
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;
}
}
am i goin' in a wrong way ??
Upvotes: 0
Views: 693
Reputation: 32437
Your 'MenuRepository' and RoleRepository
repository use different contexts. Set the context of the RoleRepository
to use the MenuRepository
's context before querying.
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;
}
}
The design suffers from leaky abstraction. Use constructor injection for repositories to inject the context. You can prevent accidentally creating multiple contexts to some extent. Use an Dependency Injection framework and make your dependencies explicit without instantiating them inside the method.
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;
}
}
Upvotes: 1