I have a doubt concerning the Entity Framework in .NET.
I have a simple ASP .NET web page that has to insert some data in SQL Server with this function:
public void InsertSimulation()
{
icarus_portalEntities entitites = new icarus_portalEntities();
// Build the Simulation
T004_SIMULATIONS tSimulation = T004_SIMULATIONS.CreateT004_SIMULATIONS(0, name_, creationDate_, gsoapPort_, endTimeStep_, scenarioX_, scenarioY_, penetrationRates_.wifi, penetrationRates_.gprs, penetrationRates_.wimax, penetrationRates_.lte, penetrationRates_.mcn, penetrationRates_.edge, penetrationRates_.hsdpa, totalNumberOfNodes_, "RandomWalkMobility", ((RandomWalkMobility)mobility_).vehicularSpeed, ((RandomWalkMobility)mobility_).angleVariation, ((RandomWalkMobility)mobility_).cellRadius, ((RandomWalkMobility)mobility_).decorrelation, ((RandomWalkMobility)mobility_).minimumDistance, false);
// Bind the Simulation with the FK of user
T001_USERS tUser = entitites.T001_USERS.First(p => p.user_name == createdBy_);
tUser.T004_SIMULATIONS.Add(tSimulation);
// Bind the Simulation with the FK of the crmm
T003_CRRM tCrmm = entitites.T003_CRRM.First(p => p.name == crmm_.Name);
tCrmm.T004_SIMULATIONS.Add(tSimulation);
// Add the created sessions to the simulation
foreach (SimulationSession session in SimulationSession.createdSessions_)
{
if (session.GetType() == typeof(WebSession))
{
// Build the session and web session
T008_SESSIONS tWebSession = ((WebSession)session).Insert(entitites);
// Bind the session to the simulation
tSimulation.T008_SESSIONS.Add(tWebSession);
}
}
// Add the enanabled technologies to the simulator
foreach (EnabledTechnologies enabled in enabledTechnologies_)
{
// Build the enabled technology
T005_ENABLED_TECHNOLOGIES tEnabled = T005_ENABLED_TECHNOLOGIES.CreateT005_ENABLED_TECHNOLOGIES(0, enabled.centerX, enabled.centerY, enabled.radius, false);
// Bind the enabled technolgy with the simulator
T002_SIMULATORS tSimulator = entitites.T002_SIMULATORS.First(p => p.id == enabled.simulatorId);
tSimulator.T005_ENABLED_TECHNOLOGIES.Add(tEnabled);
// Bind the enabled technolgoy with the simulation
tSimulation.T005_ENABLED_TECHNOLOGIES.Add(tEnabled);
}
entitites.SaveChanges();
}
The thing is that when the code tries the sentence:
// Bind the enabled technolgy with the simulator
T002_SIMULATORS tSimulator = entitites.T002_SIMULATORS.First(p => p.id == enabled.simulatorId);
It gives me the error:
The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
I found, with other related questions, that somehow the connection of the Entity object (entities
) is closed when it is passed to the method in the statement:
// Build the session and web session
T008_SESSIONS tWebSession = ((WebSession)session).Insert(entitites);
The Insert
function is implemented as:
public T008_SESSIONS Insert(icarus_portalEntities entities)
{
// Create new session object with data
T008_SESSIONS tSession = T008_SESSIONS.CreateT008_SESSIONS(0, name_, periodicty_, false);
using (entities)
{
// Create new web session object with data
T010_SESSIONS_WEB tSessionWeb = T010_SESSIONS_WEB.CreateT010_SESSIONS_WEB(0, (int)lambda_, (int)pagesPerSession_, (int)objectsSize_.alpha, (int)objectsSize_.beta, (int)objectsPerWebPage_.alpha, (int)objectsPerWebPage_.beta, (int)timeBetweenPages_.alpha, (int)timeBetweenPages_.beta, (int)timeBetweenObjects_.alpha, (int)timeBetweenObjects_.beta, false);
// Add to the session the web session (bind FK)
tSession.T010_SESSIONS_WEB.Add(tSessionWeb);
// Add session to the rest of the entities
entities.AddToT008_SESSIONS(tSession);
// Commit all the data to the database
entities.SaveChanges();
//var tempSession = entities.T008_SESSIONS.First(n => n.Equals(tSession.id));
//tempSession.T010_SESSIONS_WEB.Add(tSessionWeb);
}
return tSession;
}
The good news is that the code that Insert
function encapsulates I can move it to the place which is called. So my question is: What if there is a place in which I would be forced to call the function? How then I could avoid the error. Passing the parameter as reference (I tried and did not work)
Thank you very much in advance!
Julen.
What if there is a place in which I would be forced to call the function? How then I could avoid the error. Passing the parameter as reference (I tried and did not work)
The problem is in your Insert()
function you are wrapping entities
in a using(){}
statement.
using (entities) //calls dispose
{
}
When the using finishes it is calling dispose on your entities and closing your connection.
Your context should remain active for the lifetime of our unit of work. Ideally your using
statement should be in InsertSimulation()
as from the code it appears that is your unit of work for you entitites
.
If you look at the method public T008_SESSIONS Insert(icarus_portalEntities entities)
you are passing a reference of your entities object and because it is using a using statement
using (entities) {}
it will dispose the object
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With