I have a UsersContext : DbContext with a DbSet Users { get; set; }
UsersController.cs
public class UsersController : Controller
{
private UsersContext db = new UsersContext("dbA");
public ViewResult Index()
{
if (...)
db = new UsersContext("dbA");
else
db = new UsersContext("dbB");
return View(db.Users.ToList());
}
}
This returns the good associated list.
If I choose dbB I have the good list but when I go on detail on one of the results in :
public ViewResult Details(int id)
{
User user = db.Users.Find(id);
return View(user);
}
The db's connectionString is associated to the dbA not the dbB.
Why the new db is not well initilized and saved ?
That is because your Index action and Details action do not execute on the same controller instance. You can keep the database name in a session variable and use that to create the DbContext instance.
public class UsersController : Controller
{
private UsersContext db;
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
if (Session["Database"] == null)
db = new UsersContext("dbA");
else
db = new UsersContext((string)Session["Database"]);
}
public ViewResult Index()
{
if (...) {
db = new UsersContext("dbA");
Session
else
{
db = new UsersContext("dbB");
Session["Database"] = "dbB";
}
return View(db.Users.ToList());
}
}
Related
I have this code for deleted data from MSSQL database.
[HttpPost]
public ActionResult DeleteData(PartnerStudy partner)
{
var partnerStudy = GetByID(partner.Idetity);
DomainRepository repository = new DomainRepository();
repository.Delete(partnerStudy);
repository.SaveChanges();
return RedirectToAction("ShowData");
}
public PartnerStudy GetByID(int id)
{
DomainRepository repository = new DomainRepository();
//PartnerStudy partner = repository.GetItem<PartnerStudy>(id);
var partner = repository.GetItem<PartnerStudy>(id);
repository.Dispose();
return partner;
}
In DomainRepository have this
public void Delete<T>(T item) where T : class, IEntity
{
Set<T>().Remove(item);
}
here I have a problem.
If I try to delete have a error in line Set<T>().Remove(item);
{"The object cannot be deleted because it was not found in the
ObjectStateManager."}
What does mean ?
Why not found and where is ObjectStateManager ?
Thanks for answers!
You need to send the repository variable as a parameter to the GetByID() method, and use the same repository for getting and deleting the item.
[HttpPost]
public ActionResult DeleteData(PartnerStudy partner)
{
using(var repository = new DomainRepository())
{
var partnerStudy = GetByID(partner.Idetity, repository);
repository.Delete(partnerStudy);
repository.SaveChanges();
}
return RedirectToAction("ShowData");
}
private PartnerStudy GetByID(int id, DomainRepository repository)
{
var partner = repository.GetItem<PartnerStudy>(id);
return partner;
}
I even added a using block, as it seems DomainRepository implements IDisposable.
I have generated an entity model from database, classes are generated perfectly but when i try to use "users.ToList" class it shows me error that there is no such method. Here is the action method in controller
public class LogController : Controller
{
private myDBEntities2 db = new myDBEntities2();
[HttpPost]
public ActionResult checkLogin()
{
string name = Request["userName"];
string pass = Request["password"];
var u = db.users.ToList();
foreach (var v in u)
{
if (v.userName.Equals(name) && v.password.Equals(pass))
return RedirectToAction("items", "Product");
}
return RedirectToAction("login", "Log");
}
}
Hi this is Controller and even when I add View I keep The resource cannot be found. I even tried adding other new Controllers and I keep getting the same error.
[Route("admin")]
[RoutePrefix("user")]
public class UserController :Controller
{
private readonly IUserRepository _usersRepository;
private readonly IRoleRepository _rolesRepository;
private readonly UserService _users;
public UserController()
{
_rolesRepository = new RoleRepository();
_usersRepository = new UserRepository();
_users = new UserService(ModelState,_usersRepository,_rolesRepository);
}
// GET: Admin/User
[Route("")]
public ActionResult Index()
{
using(var manager = new StarPeaceUserManager())
{
var users = manager.Users.ToList();
return View(users);
}
}
}
I have a controller action that gets invoked directly, but throws this error:
The operation cannot be completed because the DbContext has been disposed.
I have only found solutions online regarding deferred excecution, but I don't think that applies here, because everywhere I use the context (in this instance) I call either .ToList() or .FirstOrDefault(). Here is my code:
CONTROLLER CONTENT
private IUnitOfWork UnitOfWork;
public MyFavouritesController(
IAccountServices accountServices,
IUnitOfWork unitOfWork
)
{
AccountServices = accountServices;
UnitOfWork = unitOfWork;
}
public ActionResult Index()
{
int? id = AccountServices.GetCurrentUserId();
if (!id.HasValue)
{
return RedirectToAction("Login", "Account", new { ReturnUrl = this.HttpContext.Request.Url.AbsolutePath });
}
var user = UnitOfWork.UserRepo.Get(id.Value, "Favourites", "Favourites.County", "Favourites.Country");
//THE ABOVE CALL GETS THE ERROR
//.....
return View();
}
REPOSITORY BASE CLASS
public class RepositoryBase<C, T> : IDisposable
where C:DbContext, new()
where T : ModelBase
{
private DbContext _context;
public DbContext Context
{
get
{
if (_context == null)
{
_context = new C();
this.AllowSerialization = true;
}
return _context;
}
set
{
_context = value;
}
}
public virtual T Get(int Id, params string[] includes)
{
if (Id > 0)
{
var result = Context.Set<T>().Where(t => t.Id == Id);
foreach (string includePath in includes)
{
result = result.Include(includePath);
}
return result.FirstOrDefault(); //This is where the error occurs.
}
else
{
throw new ApplicationException("Id is zero (0).");
}
}
//... (More CRUD methods)
public void Dispose()
{
if (Context != null)
{
Context.Dispose(); //Debugger never hits this before the error
}
}
}
UNIT OF WORK CLASS
public class UnitOfWork:IUnitOfWork
{
public UnitOfWork(
//... DI of all repos
IUserRepository userRepo
)
{
//... save repos to an local property
UserRepo = userRepo;
//create a new instance of the context so that all the repo's have access to the same DbContext
Context = new Context();
//assign the new context to all the repo's
//...
UserRepo.Context = Context;
}
public Context Context { get; set; }
public IUserRepository UserRepo { get; set; }
//... (some more repositories)
public void Dispose()
{
Context.Dispose(); //THIS IS NOT HIT AT ALL
}
}
LASTLY, THE MODEL CONTAINER HAS THIS LINE
_Instance.RegisterType<IUnitOfWork, UnitOfWork>(new PerThreadLifetimeManager());
As you can see, the index action will recieve a new instance of UnitOfWork which contains a new DbContext object. But at the first call to this context, it throws the above error. This pattern works everywhere else in my code.
Thanks
UPDATE
The answer below was to use a perRequestLifetimeManager. Here is the implimentation of one in unity:
public class HttpRequestLifetimeManager : LifetimeManager
{
private string _key = Guid.NewGuid().ToString();
public override object GetValue()
{
if (HttpContext.Current != null && HttpContext.Current.Items.Contains(_key))
return HttpContext.Current.Items[_key];
else
return null;
}
public override void RemoveValue()
{
if (HttpContext.Current != null)
HttpContext.Current.Items.Remove(_key);
}
public override void SetValue(object newValue)
{
if (HttpContext.Current != null)
HttpContext.Current.Items[_key] = newValue;
}
}
I noticed you're using a PerThreadLifetimeManager to control the creation and disposal of your unit of work class. You should probably change it to something like PerRequestLifetimeManager if your IoC container supports that.
Its because your are disposing the Unit Of Work, after wich you are requesting your data, store your data in a Variable after the query then you can release the Unit Of Work instance as well.
Can someone help please?
I have in my controller the create action:
public class MovieController : Controller
{
Connect connection = new Connect();
Movie movie = new Movie();
[HttpPost]
public ActionResult Create(Movie moviecreated)
{
try
{
// TODO: Add insert logic here
connection.Connection().AddObject(moviecreated);
connection.Connection().Context.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View(movie);
}
}
}
my connection class
public class Connect
{
public ObjectSet<Movie> Connection()
{
var connStr = ConfigurationManager.ConnectionStrings["Entities"];
ObjectContext context = new ObjectContext(connStr.ConnectionString);
var movieContext = context.CreateObjectSet<Movie>();
return movieContext;
}
}
It is not saving the new addition, what have I got wrong?
Thanks much.
try this:
public class MovieController : Controller
{
private Connect connection;
private Movie movie;
public MovieController()
{
this.connection = new Connect();
this.movie = new Movie();
}
[HttpPost]
public ActionResult Create(Movie moviecreated)
{
try
{
// TODO: Add insert logic here
this.connection.MovieContext.AddObject(moviecreated);
this.connection.MovieContext.Context.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View(movie);
}
}
}
public class Connect
{
private ObjectSet<Movie> movieContext;
public ObjectSet<Movie> MovieContext
{
get
{
if (this.movieContext == null)
{
this.SetMovieContext();
}
return this.movieContext;
}
}
public void SetMovieContext()
{
var connStr = ConfigurationManager.ConnectionStrings["Entities"];
var context = new ObjectContext(connStr.ConnectionString);
this.movieContext = context.CreateObjectSet<Movie>();
}
}
Each time you call connection() it creates another instance.Once you add the new record another , you try to save but different context.
Change it to a property and so save your context.