Отношение один ко многим в Entity Framework приводит к исключению - PullRequest
1 голос
/ 02 марта 2012

Чтобы познакомиться с платформой сущностей, я создал консольное приложение, которое работает с ним.

Есть две сущности: ClassA и ClassB . Между ними есть отношения один ко многим. Один экземпляр ClassA может иметь несколько экземпляров ClassB. Один экземпляр ClassB имеет 0 или 1 экземпляр ClassA.

Код для занятий:

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;}
}

Код для моего контекста базы данных и инициализатора:

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();
    }
}

Мой основной метод:

    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();
    }

Когда запускается второй цикл foreach в методе Main, выдается следующее исключение:

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)

Кажется, что свойство ClassBs в ClassA загружается неправильно. Однако в контексте я указал, что ClassA имеет много ClassB.

Соединение с базой данных выглядит нормально, так как первый экземпляр ClassA отображается на консоли. Я также могу получить доступ к базе данных в Visual Studio и посмотреть на данные, сгенерированные в инициализаторе.

Я использовал обучающие видеоролики ASP.NET MVC , чтобы начать работу с этим консольным приложением.

Вы знаете, что происходит не так?

Ответы [ 2 ]

4 голосов
/ 02 марта 2012

Вам необходимо установить для множественных активных наборов в строке подключения значение true.

MultipleActiveResultSets = true;

0 голосов
/ 02 марта 2012

Вероятно, проблема не в том, как строится модель, а в том, активирован ли MultipleActiveResultSets в соединении.См. Entity Framework: с этой командой уже есть открытый DataReader, связанный с

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...