엔티티 프레임 워크에 자신을 소개하기 위해 함께 작동하는 콘솔 응용 프로그램을 만들었습니다.Entity Framework에서 일대 다 관계가 발생하면 예외가 발생합니다.
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();
}
때 두 번째 Main 메서드의 foreach 루프가 시작될 때 다음 예외가 throw됩니다.
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)
ClassA
의 ClassBs
속성이 제대로로드되지 않은 것으로 보입니다. 그러나 나는 문맥 상 ClassA
에 ClassB
이 많은 것으로 명시했다.
ClassA의 첫 번째 인스턴스가 콘솔에 표시되기 때문에 데이터베이스 연결이 정상적으로 처리 된 것처럼 보입니다. Visual Studio에서 데이터베이스에 액세스하여 이니셜 라이저에서 생성 된 데이터를 볼 수도 있습니다.
이 콘솔 응용 프로그램을 시작하려면 training videos of ASP.NET MVC을 사용했습니다.
무엇이 잘못 됐는지 알고 있니?
db.Configuration.LazyLoadingEnabled = true로 db 컨텍스트를 생성 한 후 지연로드를 true로 설정하려고 시도하십시오. –