2009-09-03 12 views
10

Mis preguntas son probablemente muy simples, ¿cómo carga niños/subclases? No hay "carga" ni nada por el estilo que pueda encontrar para que el contexto cargue a los niños.Entity Framework 3.5 - Cómo cargar niños

la clase de contexto es de tipo ObjectContext, ver más abajo:

public partial class RTIPricingEntities : global::System.Data.Objects.ObjectContext 

Producto

Product.ModifiedByUser (cómo cargar esta clase, al cargar el producto ??)

Producto .categoría (cómo cargar las categorías al cargar el producto?)

+0

Aquí hay un ejemplo de cómo estoy cargando los datos: Quizás debería haber mencionado que estoy codificando esto para una aplicación Silverlight. Y esto es a través de un servicio de dominio. RTIPricingContext _context = new RTIPricingContext(); LoadOperation op = _context.Load (context.GetPurchaseOrderQuery(), PurchaseOrdersLoadedCallback, null); private void PurchaseOrdersLoadedCallback (LoadOperation lo) { IEnumerable po = lo.Entities.Where (w => w.UserID == SelectedUser.ID); // Esta es la colección en la que necesito llenar las subclases. – Jukeman

Respuesta

16

que es posible cargar con ganas:

var q = from p in Context.Products 
        .Include("ModifiedByUser") 
        .Include("Category") 
     select p; 

... o proyecto:

var q = from p in Context.Products 
     select new 
     { 
      Id = p.Id, 
      Name = p.Name 
      ModifiedByUserName = p.ModifiedByUser.Name, 
      CategoryName = p.Category.Name 
     } 

La ventaja de la proyección es que se consigue sólo los datos que necesita, no la totalidad de cada entidad de referencia. La ventaja de la carga ansiosa es que las entidades devueltas cambian de seguimiento. Elija la técnica correcta para el problema en cuestión.

actualización

Sí, es importante mencionar que está utilizando Servicios RIA. Supongo que también estás trabajando dentro del cliente. Esto hace que las cosas sean completamente diferentes.

En Servicios de RIA, es muy importante asegurarse de devolver todo el gráfico de las entidades que necesita en la carga inicial. No desea llamar a nada como .Load() en una entidad, porque eso sería otra candente para el servidor, lo que es malo para el rendimiento. Si está en, por ejemplo, un cliente de Silverlight y solicita una lista de instancias del servidor y sus propiedades relacionadas no están ya materializadas, ya es demasiado tarde. Además, Include no funcionará dentro de un cliente de Silverlight. Por lo tanto, RIA Services tiene herramientas del lado del servidor que puede usar para asegurarse de devolver inicialmente el gráfico de objetos correcto y totalmente materializado.

En su lugar, lo que necesita hacer es utilizar IncludeAttribute dentro de su servidor de servicios de RIA. Puede crear una clase de metadatos "amigo" para decorar su modelo de entidad con [Incluir]. Hay ejemplos en the RIA Services overview document, section 4.8.

+0

Hola, no sé si tenemos la misma versión, pero ninguna opción es posible cuando la estoy codificando. No hay ".Incluir" disponible, solo "Intersecar" ... im utilizando entidades derivadas de marcos de entidades que tiene "ObjectContext" como su clase base ... Y cuando proyecto, no hay propiedades en el intellisense para que pueda configurar ... – Jukeman

+1

Include es un método de ObjectQuery , no IQueryable . Por lo tanto, verifique el tipo de referencia que tiene. Las entidades no se derivan de ObjectContext, derivan de EntityObject. En mi ejemplo, no habrá ningún IntelliSense en el objeto proyectado porque utilicé un tipo * anónimo *. Si hubiera usado un tipo no anónimo, habría IntelliSense. –

3

Puede utilizar el método Include() del System.Data.Objects.ObjectQuery. Este método especifica los objetos relacionados que se incluirán en los resultados de la consulta y las llamadas a Include() se pueden encadenar juntas para cargar múltiples objetos relacionados.

Por ejemplo, para cargar ModifiedByUser y categoría se utilizaría una consulta como esta:

var q = from p in context.Products.Include("ModifiedByUser").Include("Category") 
     select p; 

Si su entidad por categoría también tenía una entidad ModifiedByUser que quería cargar usaría una consulta como esta:

var q = from p in context.Products 
       .Include("ModifiedByUser") 
       .Include("Category.ModifiedByUser") 
     select p; 

Consulte Shaping Query Results en MSDN para obtener más ejemplos.

+0

Veo esta solución bastante, así que debo estar haciendo algo totalmente diferente a los demás. Básicamente, estoy usando el contexto del modelo de datos que generó el entityframework. Tengo lo último de .Net. No hay disponibilidad de "Incluir". ¿Estás usando dbml/linq en este ejemplo?Estoy pensando que esta es la razón por la cual es diferente ... – Jukeman

7

El uso del .Include() como muchos otros han sugerido es una excelente manera de lograr lo que necesita.

Sin embargo, a veces puede ser necesario "volver a cargar" algo que no "incluyó" o que solo necesita a veces, por lo que poner una instrucción Include podría ser un desperdicio de ciclos de cálculo en muchos casos .

En el caso de una relación singular como "Product.Category" (donde Product.Category es su propiedad de navegación de un producto a la categoría), lo más probable es que también tenga un elemento "Product.CategoryReference". Se puede comprobar que para ver si está cargado o no, y si no, puede cargarla "a la carta":

if(!Product.CategoryReference.IsLoaded) 
{ 
    Product.CategoryReference.Load(); 
} 

Ahora su referencia "Categoría" debe estar en la memoria y listo para usar.

Si usted tiene una propiedad de navegación que hace referencia a un conjunto de cosas (por ejemplo, "partes" de un producto), puede hacer lo mismo, directamente en la propiedad de navegación:

if(!Product.Parts.IsLoaded) 
{ 
    Product.Parts.Load(); 
} 

Eso puede ser una técnica útil para "cargar a pedido" de propiedades de navegación de tipo único o de colección si no las ha "incluido" en su consulta EF.

Marc

+0

Gracias a todos, me di cuenta de que la razón por la que no pude implementar las muchas soluciones propuestas es porque el contexto es diferente una vez convertido por el servicio de dominio de Silverlight. En el código subyacente del modelo de datos de la entidad marco, puedo implementar todas sus soluciones y acabo de descubrirlo. Pero gracias a tu ayuda, sabía que el problema tenía que ser que estaba buscando en el lugar equivocado ... – Jukeman

0

me he dado cuenta de que la solución mencionada por Craig no se carga tanto el ModifiedByUser y categoría. Solo carga la última colección de objetos que en este caso es "Categoría".

var q = from p in Context.Products 
       .Include("ModifiedByUser") 
       .Include("Category") 
    select p; 

Sin embargo, si se cambia la orden, para que sea .Include("Category").Include("ModifiedByUser"), a continuación, se carga ModifiedByUser. Lo más extraño es que la propiedad IsLoaded de la colección de objetos mostrará "verdadero", sin embargo, el recuento para la primera colección de objetos siempre será cero. No estoy seguro de por qué este es el caso.