EF 4.3.1에는 Linqtenities 쿼리에 상속 된 탐색 속성이 포함되어 있습니다
-
13-12-2019 - |
문제
코드 첫 번째 승인 및 유창한 구성을 사용하여 EF 4.3.1에서 간단한 상속 시나리오를 설정하려고합니다.
일대일 탐색 속성과 상속 된 클래스 'AA'가있는 추상 기본 유형의 'a'를 만들었습니다.
public abstract class A
{
public Guid ID { get; set; }
public B ChildB { get; set; }
}
public class AA : A
{
public C ChildC { get; set; }
}
public class B
{
public Guid ID { get; set; }
public A Parent { get; set; }
}
public class C
{
public Guid ID { get; set; }
public AA Parent { get; set; }
}
public class AConfiguration : EntityTypeConfiguration<A>
{
public AConfiguration()
{
this.HasRequired(o => o.ChildB)
.WithRequiredPrincipal(o => o.Parent);
this.Map(o =>
{
o.ToTable("A");
});
}
}
public class AAConfiguration : EntityTypeConfiguration<AA>
{
public AAConfiguration()
{
this.HasRequired(o => o.ChildC)
.WithRequiredPrincipal(o => o.Parent);
this.Map(o =>
{
o.ToTable("AA");
});
}
}
public class BConfiguration : EntityTypeConfiguration<B>
{
public BConfiguration()
{
this.HasRequired(o => o.Parent)
.WithRequiredDependent(o => o.ChildB);
this.Map(o =>
{
o.ToTable("B");
});
}
}
public class CConfiguration : EntityTypeConfiguration<C>
{
public CConfiguration()
{
this.HasRequired(o => o.Parent)
.WithRequiredDependent(o => o.ChildC);
this.Map(o =>
{
o.ToTable("C");
});
}
}
public class DataContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add<A>(new AConfiguration());
modelBuilder.Configurations.Add<AA>(new AAConfiguration());
modelBuilder.Configurations.Add<B>(new BConfiguration());
modelBuilder.Configurations.Add<C>(new CConfiguration());
}
public DbSet<AA> AASet { get; set; }
public DbSet<B> BSet { get; set; }
public DbSet<C> CSet { get; set; }
}
.
Navigation 속성의 첫 번째 수준으로 데이터를 다시 가져 오려고하면 예상대로 작동합니다.
... dataContext.AASet.Include("ChildB") ...
.
그러나 다음과 같이 상속 된 유형의 탐색 속성을 포함하려고 시도 할 때 :
... dataContext.AASet.Include("ChildC") ...
.
다음 내부 예외 메시지가있는 런타임에 EntityCommandCompilationException을 얻습니다.
지정된 표현식의 ResultType은 다음과 호환되지 않습니다. 필수 유형. Expression ResuctType입니다 '일시적. 설명 [... a]'그러나 필요한 유형은 '일시적인 .Reference [... aa]'. 매개 변수 이름 : 인수 [0]
아무도 비슷한 문제가 발생 했습니까?
아마도 뭔가를 놓치고 있지만이 샘플에 무엇이 잘못되었는지 볼 수는 없습니다.
내 모델을 예상대로 작동시키기 위해 무엇을 할 수 있습니까?
해결책
아니오, 당신은 아무것도 놓치지 않습니다. 실제로 당신은 오래된 엔티티 프레임 워크 버그로 달렸습니다. 두 번째 쿼리는 다음과 같이 쓸 수 있습니다 :
var result = dataContext.ASet.OfType<AA>().Include("ChildC").ToList();
.
(dbset AASet
를 ASet
로 바꾸면)
상속 된 유형에 일대일 맵 된 어린이의 열심히로드되는이 유형의이 유형은 http://weblogs.asp.net/johnkatsiotis/archive/2010/04/28/huge-ef4-inheritance-bug.aspx
버그가 오래 전에보고되었습니다. https://connect.microsoft.com/visualstudio/feedback/details/544639/ef4-inheritance-defined-using-queryview-doesnt-work-properly-with-association < / a>
버그는 여전히 EF 4.3.1에 존재합니다. 그러나 Microsoft는 버그가 .NET 4.5 (= EF 5.0)에서 수정 된 버그가 해결되었음을 알렸습니다.
관계가 일대일 대신 한 일대일 인 경우 코드가 작동합니다. 게으른 또는 명시 적 적재는 또한 일할 수도 있습니다 (일대일 관계와 함께) 나는 믿습니다 :
var result = dataContext.ASet.OfType<AA>().ToList();
foreach (var item in result)
dataContext.Entry(item).Reference(a => a.ChildC).Load();
.
그러나 이것은 여러 쿼리를 생성합니다. 여러 쿼리에 성능 문제가없는 경우 마지막 해결 방법을 선호합니다. ef 5.0으로 마이그레이션 할 수있을 때까지