Pregunta

Tengo una jerarquía que EF (drásticamente simplificada) es como la siguiente:

class Room { EntityCollection<Session> Sessions; }
class Session { EntityCollection<Whiteboard> Whiteboards; EntityReference Room; }
class Whiteboard { EntityCollection<WhiteboardShape> WhiteboardShapes; EntityReference Session; }
abstract class WhiteboardShape { EntityReference Whiteboard; }
class WhiteboardShapeEllipse : WhiteboardShape { }
class WhiteboardShapePolyline { WhiteboardShape { EntityCollection<PolylinePoint> PolylinePoints }
class PolylinePoint { EntityReference<WhiteboardShapePolyline> WhiteboardShapePolylineReference; }

En otras palabras, una habitación puede contener varias sesiones; cada sesión puede contener múltiples pizarras; y cada pizarra puede contener múltiples WhiteboardShapes. Estas formas pueden ser de varios tipos, incluyendo un WhiteboardShapePolyline, que en sí mismo puede contener múltiples PolylinePoints.

Cuando un usuario remoto se conecta inicialmente a la habitación, tengo que pasar todo el gráfico de objetos a ese usuario, y estoy tratando de averiguar cómo cargar ese gráfico de la base de datos en la memoria tan eficientemente como sea posible.

Ahora, por supuesto, el objetivo EF permite que hagas carga ansiosos, así:

      Room room = ctx.Room
            .Include("Sessions.Whiteboards")
            .FirstOrDefault(r => r.OwnerID == ownerUserID && r.Name == roomName);

Pero include () no me deja cargar el PolylinePoints. En concreto, si lo intento:

        Room room = ctx.Room
            .Include("Sessions.Whiteboards.WhiteboardShape.PolylinePoint")
            .FirstOrDefault(r => r.OwnerID == ownerUserID && r.Name == roomName);

Me da la excepción "Un especificados incluyen ruta no es válida. El EntityType 'SlideLinc.Model.WhiteboardShape' no declara una propiedad de navegación con el nombre 'PolylinePoint'."

Tampoco funciona esto:

.Include("Sessions.Whiteboards.WhiteboardShapePolyline.PolylinePoint")

Tampoco esto:

.Include("Sessions.Whiteboards.WhiteboardShape.WhiteboardShapePolyline.PolylinePoint")

ni ninguna otra forma de enmarcar la ruta de navegación que se me ocurre.

La forma en que he terminado haciendo seguro que parece como un truco para mí:

        // Make sure we've got everything loaded.
        if (room != null)
        {
            if (!room.Sessions.IsLoaded) { room.Sessions.Load(); }
            foreach (Session session in room.Sessions)
            {
                if (!session.Whiteboards.IsLoaded) { session.Whiteboards.Load(); }
                foreach (Whiteboard whiteboard in session.Whiteboards)
                {
                    if (!whiteboard.WhiteboardShape.IsLoaded) { whiteboard.WhiteboardShape.Load(); }
                    foreach (WhiteboardShape shape in whiteboard.WhiteboardShape)
                    {
                        if (shape is WhiteboardShapePolyline)
                        {
                            WhiteboardShapePolyline polyline = (WhiteboardShapePolyline)shape;
                            if (!polyline.PolylinePoints.IsLoaded) { polyline.PolylinePoints.Load(); }
                        }
                    }
                }
            }
        }

Funciona, pero es un código mucho más de lo que yo quiero, y es un montón más de base de datos accede a lo que yo quiero.

La respuesta más cercana que he encontrado es aquí , pero mi pobre Linq- cerebro muerto de hambre no puede encontrar la manera de traducir el código de ejemplo en la jerarquía más complicado que tengo; Además, el código de ejemplo en ese enlace es maldita fea y difícil de entender. Realmente no quiero que mi jerarquía de objetos de todo en función de un efecto secundario oscura e invisible de la forma en que el EF construye internamente sus jerarquías.

¿Alguna otra sugerencia?

¿Fue útil?

Solución

utilizaría probablemente proyección para esto. En lugar de devolver los tipos de entidad, un proyecto sobre objetos ligeros de transferencia de datos o tipos anónimos. Cuando proyectas (por ejemplo, con una consulta LINQ), la carga se realiza automáticamente. No es necesario especificar un aportados en el presente caso.

Otros consejos

Estaba teniendo un problema similar al suyo (más fácil camino naviagation) y me di cuenta de que el PropertyName en el archivo Designer.cs no era lo que esperaba. Una vez que lo cambié a la PropertyName en el archivo del diseñador todo funcionó muy bien - en cuenta también hice dos caminos diferentes que se convirtieron en:

.Include("UnexpectedNameA").Include("UnexpectedNameB")
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top