Pregunta

Estamos utilizando una base de datos que no admite un lote de consulta, por lo que no podemos hacer uso de futuros nHibernate en este caso. Sabemos que aún podemos completar nuestro gráfico de objetos complejos utilizando múltiples queries (para evitar productos cartesianos) pero necesitamos asesoramiento si puedo refactorizar el enfoque.

Tenga en cuenta> Desarrollador único aquí, así que busque consejos.

Aquí hay algún código de muestra que ilustra el enfoque actual;

var fruitBasketAlias = new Store.FruitBasket(); 
var yoghurtAlias = new Store.Yoghurt();
var flavourAlias = new Store.Flavour();
var ownersAlias = new Store.Owner();

var FruitBaskets = session.QueryOver(() => fruitBasketAlias)
    .Where(() => fruitBasketAlias.Owner.ID == OwnerID
                    && fruitBasketAlias.ExpiryDate <= dateTO
                    && fruitBasketAlias.ExpiryDate >= dateFROM)
    .Fetch(x => x.BasketLiner).Eager
    .List();

session.QueryOver(() => fruitBasketAlias)
    .Select(x => x.Yoghurts)
    .Where(() => fruitBasketAlias.Owner.ID == OwnerID
                    && fruitBasketAlias.ExpiryDate <= dateTO
                    && fruitBasketAlias.ExpiryDate >= dateFROM)
    .JoinAlias(() => fruitBasketAlias.Yoghurts, () => yoghurtAlias, JoinType.LeftOuterJoin)
    .JoinAlias(() => yoghurtAlias.Flavour, () => flavourAlias, JoinType.InnerJoin)
    .List();

session.QueryOver(() => fruitBasketAlias)
    .Where(() => fruitBasketAlias.Owner.ID == OwnerID
                    && fruitBasketAlias.ExpiryDate <= dateTO
                    && fruitBasketAlias.ExpiryDate >= dateFROM)
    .JoinAlias(() => fruitBasketAlias.Yoghurt, () => yoghurtAlias, JoinType.LeftOuterJoin)
    .JoinAlias(() => yoghurtAlias.Flavour, () => flavourAlias, JoinType.InnerJoin)
    .JoinAlias(() => flavourAlias.Owners, () => ownersAlias, JoinType.LeftOuterJoin)
    .List();

Puede ver en el código anterior que estoy usando tres consultas separadas para llenar una lista de boquetas de frutas. Este enfoque está funcionando, pero sospecho que hay una mejor manera de unirse a todos los niños al objeto principal sin tener que consultar desde el objeto raíz cada vez.

¿Hay un enfoque que pueda usar que me permita aplicar la condición Where al objeto principal y usar los resultados de esa consulta para obtener automáticamente todos los objetos de los niños? Tenga en cuenta que los niños pueden ir 3 niveles de profundidad, es decir, fruitbasket.yoghurt.flavour.nowners.

Se agradece cualquier consejo.

C# .NET 4, nHibernate 3.0

¿Fue útil?

Solución

var FruitBaskets = session.QueryOver<FuitBasket>()
    .Where(b => b.Owner.ID == OwnerID
                    && b.ExpiryDate <= dateTO
                    && b.ExpiryDate >= dateFROM)
    .Fetch(x => x.BasketLiner).Eager
    .JoinAlias(b => b.Yoghurts, () => yoghurtAlias, JoinType.LeftOuterJoin)
    .List();

var yoghurts = session.QueryOver<Store.Yoghurt>()
    .WhereRestrictionOn(y => y.Id).In(FruitBaskets.SelectMany(b => b.Yoghurts).Select(y = > y.Id).Distinct())
    .JoinAlias(y => y.Flavour, () => flavourAlias, JoinType.InnerJoin)
    .List();

session.QueryOver<Store.Flavor>()
    .WhereRestrictionOn(f => f.Id).In(yoghurts.SelectMany(y => y.Flavors).Select(b = > f.Id).Distinct())
    .JoinAlias(f => f.Owners, () => ownersAlias, JoinType.LeftOuterJoin)
    .List();

Aunque no pudo probarlo

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top