Entity Framework-Include ()없이 자식 엔터티를 자동으로 즉시로드하는 방법이 있습니까?
POCO 클래스를 장식하여 자식 엔터티 Include()
를로드 할 때마다 사용할 필요없이 자동으로 즉시 로드하는 방법이 있습니까?
Wheels, Doors, Engine, Bumper, Windows, Exhaust 등에 대한 복잡한 유형의 속성을 가진 Class Car가 있다고 가정합니다. 그리고 내 앱에서 다른 쿼리 등으로 DbContext 20 개의 다른 위치에서 내 차를로드해야합니다. 차를 싣고 싶을 때마다 모든 속성을 포함하도록 지정할 필요는 없습니다.
나는 말하고 싶다
List<Car> cars = db.Car
.Where(x => c.Make == "Ford").ToList();
//NOT .Include(x => x.Wheels).Include(x => x.Doors).Include(x => x.Engine).Include(x => x.Bumper).Include(x => x.Windows)
foreach(Car car in cars)
{
//I don't want a null reference here.
String myString = car.**Bumper**.Title;
}
어떻게 든 내 POCO 클래스를 장식하거나 OnModelCreating()
EF에서 구성을 설정하여 내 차를로드 할 때 내 차의 모든 부품을로드하도록 지시 할 수 있습니까? 이 작업을 열심히하고 싶기 때문에 내 탐색 속성을 가상으로 만드는 것이 나왔습니다. NHibernate가 유사한 기능을 지원한다는 것을 알고 있습니다.
내가 뭔가를 놓치고 있는지 궁금합니다. 미리 감사드립니다!
건배,
나단
아래 솔루션이 마음에 들지만 확장 메서드에 대한 호출을 중첩 할 수 있는지 궁금합니다. 예를 들어, 내가 어디에나 포함하고 싶지 않은 부품이 많은 엔진과 비슷한 상황이 있다고 가정 해 보겠습니다. 이런 식으로 할 수 있습니까? (아직 작동하는 방법을 찾지 못했습니다). 이렇게하면 나중에 엔진에 FuelInjector가 필요하다는 것을 알게되면 BuildEngine에만 추가 할 수 있으며 BuildCar에도 추가 할 필요가 없습니다. 또한 호출을 중첩 할 수있는 경우 컬렉션에 호출을 중첩하려면 어떻게해야합니까? 내 BuildCar () 내에서 각 휠에 대해 BuildWheel ()을 호출하고 싶습니까?
public static IQueryable<Car> BuildCar(this IQueryable<Car> query) {
return query.Include(x => x.Wheels).BuildWheel()
.Include(x => x.Doors)
.Include(x => x.Engine).BuildEngine()
.Include(x => x.Bumper)
.Include(x => x.Windows);
}
public static IQueryable<Engine> BuildEngine(this IQueryable<Engine> query) {
return query.Include(x => x.Pistons)
.Include(x => x.Cylendars);
}
//Or to handle a collection e.g.
public static IQueryable<Wheel> BuildWheel(this IQueryable<Wheel> query) {
return query.Include(x => x.Rim)
.Include(x => x.Tire);
}
이 상황에서 다른 사람에게 도움이되는 경우를 대비하여 매우 유사한 또 다른 스레드가 있지만 확장 메서드에 대한 다음 호출을 처리 할 수 없습니다.
엔티티 프레임 워크 linq 쿼리 Include () 여러 하위 엔티티
아니요 매핑에서는 그렇게 할 수 없습니다 . 일반적인 해결 방법은 간단한 확장 방법입니다.
public static IQueryable<Car> BuildCar(this IQueryable<Car> query) {
return query.Include(x => x.Wheels)
.Include(x => x.Doors)
.Include(x => x.Engine)
.Include(x => x.Bumper)
.Include(x => x.Windows);
}
이제 Car
모든 관계 를 쿼리 할 때마다 다음을 수행합니다.
var query = from car in db.Cars.BuildCar()
where car.Make == "Ford"
select car;
편집하다:
그런 식으로 호출을 중첩 할 수 없습니다. 작업중인 핵심 엔터티에 대한 작업을 포함합니다. 해당 엔터티는 쿼리의 모양을 정의하므로 호출 한 후에도 Include(x => Wheels)
계속 작업하고 IQueryable<Car>
있으며에 대한 확장 메서드를 호출 할 수 없습니다 IQueryable<Engine>
. 다음으로 다시 시작해야합니다 Car
.
public static IQueryable<Car> BuildCarWheels(this IQuerable<Car> query) {
// This also answers how to eager load nested collections
// Btw. only Select is supported - you cannot use Where, OrderBy or anything else
return query.Include(x => x.Wheels.Select(y => y.Rim))
.Include(x => x.Wheels.Select(y => y.Tire));
}
이 방법을 다음과 같이 사용합니다.
public static IQueryable<Car> BuildCar(this IQueryable<Car> query) {
return query.BuildCarWheels()
.Include(x => x.Doors)
.Include(x => x.Engine)
.Include(x => x.Bumper)
.Include(x => x.Windows);
}
Include(x => x.Wheels)
중첩 된 엔터티의 즉시로드를 요청할 때 자동으로 추가되어야하므로 사용이 호출되지 않습니다 .
Beware of complex queries produced by such complex eager loading structures. It may result in very poor performance and a lot of duplicate data transferred from the database.
Had this same problem and saw the other link which mentioned an Include
attribute. My solution assumes that you created an attribute called IncludeAttribute
. With the following extension method and utility method:
public static IQueryable<T> LoadRelated<T>(this IQueryable<T> originalQuery)
{
Func<IQueryable<T>, IQueryable<T>> includeFunc = f => f;
foreach (var prop in typeof(T).GetProperties()
.Where(p => Attribute.IsDefined(p, typeof(IncludeAttribute))))
{
Func<IQueryable<T>, IQueryable<T>> chainedIncludeFunc = f => f.Include(prop.Name);
includeFunc = Compose(includeFunc, chainedIncludeFunc);
}
return includeFunc(originalQuery);
}
private static Func<T, T> Compose<T>(Func<T, T> innerFunc, Func<T, T> outerFunc)
{
return arg => outerFunc(innerFunc(arg));
}
'Programing' 카테고리의 다른 글
Varargs Java 모호한 호출 (0) | 2020.11.09 |
---|---|
포인터에 메모리 할당 여부 확인 (0) | 2020.11.09 |
Just-In-Time 컴파일과 Ahead-of-Time 컴파일의 장점은 무엇입니까? (0) | 2020.11.09 |
CSS에 값이있는 속성으로 요소를 타겟팅하려면 어떻게해야합니까? (0) | 2020.11.08 |
jQuery에서 브라우저 스크롤 위치를 어떻게 얻습니까? (0) | 2020.11.08 |