none
EF interpreta mi tabla como una Association, cómo la consulto y actualizo? RRS feed

  • Pregunta

  • Tengo en SQL Server una tabla de mtto_TipoMantenimiento con todos los posibles tipos de mantenimiento según los tipos de equipo y tengo otra tabla mtto_ActividadMtto con todas las actividades posibles que se hacen en un taller, además otra tabla, en la que tengo para cada tipo de mantenimiento cuáles actividades se le deben realizar (mtto_ActividadTipoMantenimiento), esta tercera tabla EF me la interpreta como una Association muchos a muchos de mis dos primeras tablas, las tablas mostradas en el diagrama con azul son las que EF me agregó tal cual, la que está con rojo es la que faltó como tabla y me la puso como Association.

    La pregunta es, dentro de mi aplicación, voy a agregar una opción, en la que el usuario administrador del sistema, va a seleccionar un Tipo de Mantenimiento y le va a asignar todas la Actividades que se le deben realizar, pero si EF no me agrega mi tercera tabla como tal, cómo le hago para registrar todo esto en mi tercera tabla?? así mismo, cómo hago para consultar para algún Tipo de Mantenimiento, todas las Actividades que tiene registradas??

    La Metadata que se me generó en forma automática de estas tablas están así:

        [MetadataTypeAttribute(typeof(mtto_TipoMantenimiento.mtto_TipoMantenimientoMetadata))]
        public partial class mtto_TipoMantenimiento
        {
            internal sealed class mtto_TipoMantenimientoMetadata
            {
                private mtto_TipoMantenimientoMetadata()
                {
                }
                public string ClaveMtto { get; set; }
    
                public bool Estatus { get; set; }
    
                public int Frecuencia { get; set; }
    
                public int ID { get; set; }
    
                public int IDTipoEquipo { get; set; }
    
                public EntityCollection<mtto_ActividadMtto> mtto_ActividadMtto { get; set; }
    
                public EntityCollection<mtto_RefaccionTipoMantenimiento> mtto_RefaccionTipoMantenimiento { get; set; }
    
                public mtto_TipoEquipo mtto_TipoEquipo { get; set; }
    
                public double TiempoEstandarHrs { get; set; }
                public string UnidadFrecuencia { get; set; }     
            }
        }
        [MetadataTypeAttribute(typeof(mtto_ActividadMtto.mtto_ActividadMttoMetadata))]
        public partial class mtto_ActividadMtto
        {
            internal sealed class mtto_ActividadMttoMetadata
            {
                private mtto_ActividadMttoMetadata()
                {
                }
    
                public string Descripcion { get; set; }
    
                public bool Estatus { get; set; }
    
                public int ID { get; set; }
    
                public EntityCollection<mtto_TipoMantenimiento> mtto_TipoMantenimiento { get; set; }
    
            }
        }

    Y la asociación que me generó tiene estas propiedades:


    Estoy usando:

    Microsoft Visual Studio Professional 2012
    Versión 11.0.60610.01 Update 3
    Microsoft .NET Framework
    Versión 4.5.50709

    Silverlight 5.0

    Soy completamente nueva en todo esto EF, Silverlight, Visual Studio, C#, RIA Services, cualquier orientación será infinitamente agradecida, saludos


    cyndyrdz

    lunes, 24 de marzo de 2014 19:06

Respuestas

Todas las respuestas

  • hola

    la consulta es directa, con solo definir el Include() cn la propiedad de navegacion recupera las sociaciones

    veras en el diagrama que figura una propiedad mtto_TipoMantenimiento es por medio de esta propiedad que navegas la relacion

    podrias hacer

    var actividad = context.mtto_ActividadMtto.Include("mtto_TipoMantenimiento").Where(x=> x.ID = valor);

    con esto solo podrias hacer

    var tipoMantenimientoList = actividad.mtto_TipoMantenimiento;

    y recuperar las relaciones

    para actualizar es lo mismo agregas un item a la coleccion y realizas el SaveChanges()

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    martes, 25 de marzo de 2014 23:38
  • Muchas gracias por responder Leandro, pero no entiendo nada....o lo que entiendo no es lo correcto...o algo está mal....

    Selecciono de un ComboBox el Tipo de Mtto y quiero ver todas sus actividades, entonces:

    MTTO.Web.DomainServiceMTTO Mtto = new DomainServiceMTTO();
    
                mtto_TipoMantenimiento myTipoMantenimiento = (mtto_TipoMantenimiento)cbmtto_TipoMantenimiento.SelectedItem;
                var actividad = Mtto.mtto_TipoMantenimientos.Include("mtto_ActividadMtto").Where(x=> x.ID = myTipoMantenimiento.ID);

     Al compilar me marca un error:

    Entonces intento agregar [Include] en el DomainServiceMTTO.metadata.cs en la parte de mtto_TipoMantenimiento donde define la colección de mtto_ActividadMtto:

                [Include]
                public EntityCollection<mtto_ActividadMtto> mtto_ActividadMtto { get; set; }

    Compilo, y entonces me dá el error:

    Así, que quito ese [Include] e intento ponerlo al revés, en la tabla mtto_ActividadMtto:

                [Include]
                public EntityCollection<mtto_TipoMantenimiento> mtto_TipoMantenimiento { get; set; }
    Compilo y me da el mismo error de Especificación Include no válida...

     


    cyndyrdz


    • Editado Cynthia Rodriguez miércoles, 26 de marzo de 2014 15:28 me equivoqué de imagen
    miércoles, 26 de marzo de 2014 15:25
  • la clase DomainServiceMTTO es tu contexto de EF ?

    el intelisense del VS no te muestra el metodo Include()

    porque este metodo existe lo he usaod miles de veces para cargar relaciones

    Cargar objetos relacionados (Entity Framework)

    esludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    miércoles, 26 de marzo de 2014 17:42
  • Leandro, de hecho te iba a preguntar que qué es para ti el context.mtto_ActividadMtto, en mi caso, cuando agregué la clase de servicio me generó automáticamente un "archivo" DomainServiceMTTO.cs, el cual comienza así:

    namespace MTTO.Web
    {
        using System;
        using System.Collections.Generic;
        using System.ComponentModel;
        using System.ComponentModel.DataAnnotations;
        using System.Data;
        using System.Linq;
        using System.ServiceModel.DomainServices.EntityFramework;
        using System.ServiceModel.DomainServices.Hosting;
        using System.ServiceModel.DomainServices.Server;
    
        // Implementa la lógica de la aplicación mediante el contexto MTTOEntities.
        // TODO: agregue la lógica de su aplicación a estos métodos o en métodos adicionales.
        // TODO: aplique la autenticación (Windows/ASP.NET Forms) y quite las marcas de comentario de lo siguiente para deshabilitar el acceso anónimo
        // Considere además la posibilidad de agregar roles para restringir el acceso según necesidad.
        // [RequiresAuthentication]
        [EnableClientAccess()]
        public class DomainServiceMTTO : LinqToEntitiesDomainService<MTTOEntities>
        {
            // 24/02/2014 CYRM Agregué un método de consulta para el SP pa_mtto_Operadores
            public IQueryable<pa_mtto_Operadores_Result> pa_mtto_Operadores()
            {
                return this.ObjectContext.pa_mtto_Operadores().AsQueryable<pa_mtto_Operadores_Result>();
            }

    Aquí se generaron todos los métodos de CRUD en automático para todas mis tablas, y yo agregué algunos y modifiqué otros

    La pantalla donde lo agregué es algo así:

    Aquí le puse el nombre de DomainServiceMTTO y seleccioné todas mis tablas, marcando Habilitar Edición.

    Cuando en una forma hago:

     MTTO.Web.DomainServiceMTTO Mtto = new DomainServiceMTTO();
    puedo acceder desde Mtto a sus elementos como en el ejemplo que te puse.

    Voy a revisar el link que me enviaste, saludos y gracias de nuevo


    cyndyrdz


    miércoles, 26 de marzo de 2014 19:39
  • Leandro, además de lo que acabo de poner, te hago otro comentario, revisando un poco la documentación que me enviaste, veo que utilizan por ejemplo AdventureWorksEntities context = new AdventureWorksEntities(), esto me hace pensar que en mis formas yo debería poder utilizar, en forma similar algo como:

    MTTOEntities context = new MTTOEntities()

    Pero no sé porqué no puedo tener acceso a MTTOEntities, me marca el error:

    "No se puede encontrar el tipo o el nombre de espacio de nombres 'MTTOEntities' (¿Falta una directiva using o una referencia de ensamblado?)

    Por cierto, MTTOEntities si se utiliza en el DomainServiceMTTO.cs, como viene en el ejemplo de código que te mandé justo antes de esta respuesta.

    Será esta la clave? qué me falta poner o agregar??


    cyndyrdz

    miércoles, 26 de marzo de 2014 21:46
  • hola

    la verdad no se que has creado pero el usar esa clase service que hereda de LinqToEntitiesDomainService quiere decir que has creado un  WCF RIA Services

    o sea son servicio REST por eso no aparece el Include() no estas usando entity framework sino que estas exponiendo el modelo como servicio web con WCF

    cuando generaste el codigo que opcion del VS utilizaste ?

    verdaderamente quiere usar servicio web ?

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    jueves, 27 de marzo de 2014 10:16
  • Leandro, exacto, sabía que algo era diferente a lo que me presentaban

    Si, utiicé RIA Services, mi aplicación es del tipo "Aplicación de Silverlight", cuando la creé marqué la opción de "Habilitar servicios de RIA de WCF" y para realizar los accesos a la BD seguí un tutorial de Jorge Levy: http://www.jorgelevy.com/index.php/2012/05/wcf-ria-services-v1-0-para-silverlight-4-agregar-un-nuevo-registro-hacia-la-base-de-datos-parte-8/#/index.php/category/silverlight/wcf-ria-services-v1-0/ en el que se agrega un "Domain Service Class" (que corresponde a la última imagen que te anexé) la cual como has visto llamé DomainServiceMTTO.cs

    Mi aplicación será utilizada dentro de la empresa, como una aplicación de escritorio, básicamente con usuarios de un par de departamentos, con acceso a la BD en un servidor en red.

    Gracias


    cyndyrdz

    jueves, 27 de marzo de 2014 14:26
  • Para que no se quede este link abierto, anexo la solución que conseguí en el Foro en Inglés: http://social.msdn.microsoft.com/Forums/silverlight/en-US/6c1bf1d4-2756-4319-b954-07e5afeeac7d/wcf-ria-interprets-my-table-as-an-association-how-i-can-read-it-and-update-it?forum=silverlightwcf

    This is called a Many to Many or M2M relationship. RIA Services does not directly support M2M although there is something called M2M4RIA that can add it to WCF RIA Services and we are working on adding native support to Open RIA Services. The easiest solution is to change your linking table to have another column in it, at least temporarily. It doesn't matter what the column is, just that it isn't a foreign key to the linked tables. After you do that Entity Framework will not see it as a M2M linking table and will add it as a normal table to the EDMX. Once the EDMX is setup, you can remove that extra column if you wish.


    http://www.openriaservices.net | RIA Services and MVVM http://bit.ly/pgL97k

    <input id="a9f53fe1-b1e4-489b-939c-32d05218abe8_attachments" type="hidden" value="" />                

    cyndyrdz

    miércoles, 16 de abril de 2014 16:51