2011-09-21 19 views
12

tengo una clase como se muestra a continuacióncómo serializar propiedad de tipo ICollection <T> durante el uso de Entity Framework

public class Survey 
    { 
     public Survey() 
     { 
      SurveyResponses=new List<SurveyResponse>(); 
     } 

     [Key] 
     public Guid SurveyId { get; set; } 
     public string SurveyName { get; set; } 
     public string SurveyDescription { get; set; } 
     public virtual ICollection<Question> Questions { get; set; } 
     public virtual ICollection<SurveyResponse> SurveyResponses { get; set; } 
    } 

El código anterior me da siguiente excepción

No se puede serializar miembro de 'SurveyGenerator.Survey. Preguntas del tipo 'System.Collections.Generic.ICollection

Cuando convierto el ICollection a la lista serializa adecuadamente

Puesto que se POCO del marco de la entidad, no puedo convertir ICollection a la lista

+0

Comprobar si esa respuesta le ayudará a http: // stackoverflow.com/a/21660262/1488939 –

+0

¿Qué ocurre si utiliza la lista en lugar de ICollection con EF Code First? Tenía la impresión de que todavía funcionaba. – CDeutsch

Respuesta

2

Desde el aspecto de su clase de las propiedades ICollection están definiendo relaciones de clave externa? Si es así, no le gustaría exponer públicamente las colecciones.

Por ejemplo: Si usted está siguiendo la guía de mejores prácticas para el desarrollo de modelos de Entity Framework, entonces tendría una clase separada llamada "Pregunta" que cablear su clase dos juntos, lo que podría tener el siguiente aspecto:

public class Question 
{ 
    [Key] 
    public int Id { get; set; } 
    public string Title { get; set; } 
    public string Description { get; set; } 

    public virtual Survey Survey { get; set; } 
} 

Si este fuera el caso, podría muy posiblemente va en círculos llamando a la pregunta -> Encuesta -> ICollection -> pregunta

tuve un incidente similar usando EF, MVC3 para implementar un servicio REST y couldn serializar el objeto ICollection <> y luego me di cuenta de que no era necesario estaría llamando al objeto por separado de todos modos.

La clase actualizada para sus propósitos se vería así:

public class Survey 
{ 
    public Survey() 
    { 
     SurveyResponses=new List<SurveyResponse>(); 
    } 

    [Key] 
    public Guid SurveyId { get; set; } 
    public string SurveyName { get; set; } 
    public string SurveyDescription { get; set; } 

    [XmlIgnore] 
    [IgnoreDataMember] 
    public virtual ICollection<Question> Questions { get; set; } 

    [XmlIgnore] 
    [IgnoreDataMember] 
    public virtual ICollection<SurveyResponse> SurveyResponses { get; set; } 
} 

I espera que esto te ayuda.

+1

Este artículo me sanó en combinación con esta respuesta http://geekswithblogs.net/danemorgridge/archive/2010/05/04/entity-framework-4-wcf-amp-lazy-loading-tip.aspx –

1

Cambiar el ICollection <T> a una lista <T>

public class Survey 
{ 
    public Survey() 
    { 
     SurveyResponses=new List<SurveyResponse>(); 
    } 

    [Key] 
    public Guid SurveyId { get; set; } 
    public string SurveyName { get; set; } 
    public string SurveyDescription { get; set; } 
    public virtual List<Question> Questions { get; set; } 
    public virtual List<SurveyResponse> SurveyResponses { get; set; } 
} 
1

Si no te importa la adición de una referencia a la System.Runtime.Serialization ensamblaje, puede utilizar este código que serializará un objeto con ICollection sin necesidad de cambiar la implementación del objeto. El siguiente código está saliendo a la cadena. Puedes usar la transmisión como quieras.

private string ConvertClassToXMLString<T>(T classObject) 
    { 
     using (var stream = new MemoryStream()) 
     { 
      var serializer = new DataContractSerializer(classObject.GetType()); 
      serializer.WriteObject(stream, classObject); 

      return Encoding.UTF8.GetString(stream.ToArray()); 
     } 
    } 
0

Utilicé la solución Matthew Merryfull y funciona.

Como utilizo el diseñador de EF para la generación de entidades cada vez que actualizo mis modelos, pierdo los cambios manuales. Tuve que cambiar * .tt que se usa para la generación de modelos. He editado pocas líneas:

public string NavigationProperty(NavigationProperty navigationProperty) 
{ 
var enbleWebService = string.Empty; 
if(navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many){ 
enbleWebService = string.Format("[XmlIgnore]{0}[IgnoreDataMember]{0}", Environment.NewLine); 
} 
    var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType()); 
    return string.Format(
     CultureInfo.InvariantCulture, 
     "{5} {0} {1} {2} {{ {3}get; {4}set; }}", 
     AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)), 
     navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, 
     _code.Escape(navigationProperty), 
     _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)), 
     _code.SpaceAfter(Accessibility.ForSetter(navigationProperty)), 
     _code.Escape(enbleWebService)); 
} 

public string NavigationProperty(NavigationProperty navigationProperty) 
{ 
var enbleWebService = string.Empty; 
if(navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many){ 
    enbleWebService = string.Format("[XmlIgnore]{0}[IgnoreDataMember]{0}", Environment.NewLine); 
} 
    var endType = _typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType()); 
    return string.Format(
     CultureInfo.InvariantCulture, 
     "{5} {0} {1} {2} {{ {3}get; {4}set; }}", 
     AccessibilityAndVirtual(Accessibility.ForProperty(navigationProperty)), 
     navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType, 
     _code.Escape(navigationProperty), 
     _code.SpaceAfter(Accessibility.ForGetter(navigationProperty)), 
     _code.SpaceAfter(Accessibility.ForSetter(navigationProperty)), 
     _code.Escape(enbleWebService)); 
} 

También puedes ver este artículo en caso de que tenga problemas con la serialización http://geekswithblogs.net/danemorgridge/archive/2010/05/04/entity-framework-4-wcf-amp-lazy-loading-tip.aspx

Cuestiones relacionadas