Question

I'm pretty new c# and MVC, and today i've been playing around with DB4o. I've put together a practice site which scrapes films via a url provided by a user. The films are then stored in a db4o database. However, I now seem to be getting a Db4objects.Db4o.Ext.DatabaseClosedException
thrown everytime I launch the site. I have a feeling that I'm making too many calls to the DB, without closing the current connection.

Here is my controller, which I believe the problem stems from.

  using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Web.Mvc;
  using MvcMovieDatabase.Models;
  using Db4objects.Db4o;
  using Db4objects.Db4o.Linq;


  using System.IO;namespace MvcMovieDatabase.Controllers
  {
      public class HomeController : Controller
      {
           static string YapFileName = Path.Combine(      
           Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
                           "moviesDB.yap");

    IObjectContainer db4o = Db4oEmbedded.OpenFile(YapFileName);

    public ActionResult Index()
    {
        ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";

        return View();
    }

    public ActionResult About()
    {
        ViewBag.Message = "Your app description page.";

        return View();
    }

    public ActionResult Contact()
    {
        ViewBag.Message = "Your contact page.";

        return View();
    }

    [HttpGet]
    public ActionResult Create()
    {
        return View();
    }

    [HttpPost]
    public ActionResult Create(string movieURL)
    {
        Movie newMovie = new Movie();
        MovieDirectory dir = new MovieDirectory();

        newMovie = dir.GetMovieData(movieURL);

        db4o.Store(newMovie);

        db4o.Close();

        return RedirectToAction("Index");
    }

    public ActionResult DB4o()
    {

        IEnumerable<Movie> allFilms = from movie in db4o.Query<Movie>()
                                      select movie;

        db4o.Close();

        return View(allFilms);
    }


   }
 }

The create method takes a string and runs the necessary code to grab the data. The db4o method just runs a query to grab the stored data from the db. I started closing, and opening streams, just to see if I could spot the problem, but then it started throwing the same exception for this piece of code inside the View of db40 method.

 @model IEnumerable<MvcMovieDatabase.Models.Movie>

 @{
      ViewBag.Title = "DB4o";
  }

  <h2>DB4o</h2>

  @foreach (var item in Model)
  {
      foreach (var cast in item.MovieCastList)
      {
          <p><img src="@cast.CastImage" /></p>
          <p>@cast.CastRealName | <span>@cast.CastFilmName</span></p>
      }
  }

However, this may be probably down to my meddling. Thanks for any help with this matter.

Was it helpful?

Solution

The problem seems to be that you are closing the connection after each create. db4o ObjectContainers are intended to be kept open all the time your application runs. Look at this link for more info.

If you are still willing to open and close the connection after each update, then you should place the following line at the beginning of method Create()

IObjectContainer db4o = Db4oEmbedded.OpenFile(YapFileName);

You are opening the Object Container once, but closing it after each transaction.

Hope this helps.

OTHER TIPS

as Gonzalo described you must not close db4o session in your application. If you would like to use isolated transactions use OpenSession like:

IEnumerable allFilms = null;
using (var session = db4o.Ext().OpenSession())
{
    // query
    allFilms = from movie in session.Query()
               select movie;

    // do object activation here or rely on default activation level
    foreach (var movie in allFilms)
    {
        session.Activate(movie, int.MaxValue);
    }
}

return View(allFilms);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top