Pergunta

Eu tenho uma hierarquia de EF que (dramaticamente simplificado) é algo como isto:

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; }

Em outras palavras, um quarto pode conter várias sessões; cada sessão pode conter vários quadros; e cada quadro branco pode conter vários WhiteboardShapes. Estas formas podem ser de vários tipos, incluindo uma WhiteboardShapePolyline, que em si pode conter vários PolylinePoints.

Quando um usuário remoto se conecta inicialmente para a sala, eu preciso passar todo o gráfico do objeto para o usuário, e eu estou tentando descobrir como colocar esse gráfico do banco de dados na memória de forma tão eficiente quanto possível.

Agora, é claro, a EF permite que você faça o carregamento ansioso, assim:

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

Mas Incluir () não me deixa carregar as PolylinePoints. Especificamente, se eu tentar:

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

Eu recebo a exceção "A especificado Incluir caminho não é válido. Será que o EntityType 'SlideLinc.Model.WhiteboardShape' não declarar uma propriedade de navegação com o nome 'PolylinePoint'."

Nem isso funciona:

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

Nem faz isso:

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

Nem qualquer outra forma de enquadrar a caminho de navegação que eu posso pensar.

A maneira que eu acabei fazendo isto seguro parece como um hack para mim:

        // 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(); }
                        }
                    }
                }
            }
        }

Ele funciona, mas é um código muito mais do que eu quero, e é um grupo inteiro mais banco de dados acessa do que eu quero.

A resposta mais próximo que eu encontrei é aqui , mas minha pobre Linq- cérebro fome não consegue descobrir como traduzir o código de exemplo na hierarquia mais complicado que eu tenho; Além disso, o código de exemplo em que o link seja condenado feio e difícil de entender. Eu realmente não quero toda a minha hierarquia de objetos de acordo com um efeito colateral obscuro e invisível de como a EF constrói internamente suas hierarquias.

Qualquer outra sugestão?

Foi útil?

Solução

Eu provavelmente usar a projeção para este. Em vez de retornar tipos de entidade, projeto em objetos de transferência de dados leves ou tipos anônimos. Quando você projetar (por exemplo, com uma consulta LINQ), o carregamento acontece automaticamente. Você não precisa especificar um Incluir neste caso.

Outras dicas

Eu estava tendo um problema semelhante ao seu (mais fácil caminho naviagation) e percebi que o PropertyName no arquivo Designer.cs não era o que eu esperava. Uma vez que eu mudei para o PropertyName no arquivo Designer tudo funcionou bem - também notar que eu fiz dois caminhos diferentes que se tornou:

.Include("UnexpectedNameA").Include("UnexpectedNameB")
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top