To introduce myself to the entity framework I created a console application that works with it.
There are two entities: ClassA and ClassB. There is a one-to-many relationship between them. One instance of ClassA can have multiple instances of ClassB. One instance of ClassB has 0 or 1 instance of ClassA.
The code for the classes is:
public class ClassA {
public virtual int Id {get; set;}
public virtual string Name {get; set;}
public virtual ICollection<ClassB> ClassBs {get; set;}
}
public class ClassB {
public virtual int Id {get; set;}
public virtual string Name {get; set;}
public virtual ClassA ClassA {get; set;}
}
The code for my database context and initializer is:
public class Context : DbContext {
public DbSet<ClassA> ClassAs {get; set;}
public DbSet<ClassB> ClassBs {get; set;}
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<ClassA>()
.HasMany(classA => classA.ClassBs)
.WithRequired(classB => classB.ClassA);
base.OnModelCreating(modelBuilder);
}
}
public class Initializer : DropCreateDatabaseAlways<Context> {
protected override void Seed(Context context) {
base.Seed(context);
for (int i = 1; i <= 3; i++) {
var classA = new ClassA{
Name = "A-" + i,
ClassBs = new LinkedList<ClassB>()
};
for (int j = 1; j <= 3; j++) {
var classB = new ClassB{
Name = "B-" + i + "-" + j,
ClassA = classA
};
classA.ClassBs.Add(classB);
context.ClassBs.Add(classB);
}
context.ClassAs.Add(classA);
}
context.SaveChanges();
}
}
My Main method is:
static void Main(string[] args) {
Database.SetInitializer(new Initializer());
Context db = new Context();
foreach (var classA in db.ClassAs) {
Console.WriteLine(classA.Name);
foreach (var classB in classA.ClassBs)
Console.WriteLine("\t" + classB.Name);
}
Console.Write("\nFIN");
Console.ReadKey();
}
When the second foreach loop in the Main method starts the following exception is thrown:
System.Data.EntityCommandExecutionException was unhandled
Message=An error occurred while executing the command definition. See the inner exception for details.
Source=System.Data.Entity
InnerException: System.InvalidOperationException
Message=There is already an open DataReader associated with this Command which must be closed first.
Source=System.Data
StackTrace:
at System.Data.SqlClient.SqlInternalConnectionTds.ValidateConnectionForExecute(SqlCommand command)
at System.Data.SqlClient.SqlConnection.ValidateConnectionForExecute(String method, SqlCommand command)
at System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method)
at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method)
at System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.EntityClient.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
It seems that the ClassBs property in ClassA is not loading properly. However I did specify in the context that ClassA has many ClassB.
The database connection seems fine, since the first instance of ClassA is displayed on the console. I can also acces the database in Visual Studio and look at the data generated in the initializer.
I used the training videos of ASP.NET MVC to get started with this console application.
Do you know what’s going wrong?
You need to set multipleactiveresultsets in your connection string to true.
MultipleActiveResultSets=true;