简体   繁体   中英

Can I get the entity framework to use concrete classes instead of interfaces (for web service serialisation)

I am learning about web services and the book I am using is pulling data from SQL server using the entity framework (which I know little about too).

Unfortunately the classes created by the entity framework contain things like:

public Conference()
{
   this.Sessions = new HashSet<Session>();
}
public virtual ICollection<Session> Sessions { get; set; }

Which causes a problem because an interface is not serialisable:

Cannot serialize member X of type System.Collections.Generic.ICollection ... because it is an interface.

Now I could (and did) modify the generated classes to use concrete classes but if I ever need to regenerate the entities then that change will be undone. Ideally I could tell the entity framework to generate something like this (or even better, have control of the concrete type so I could tell the entity framework to use a List if I want to):

public Conference()
{
   this.Sessions = new HashSet<Session>();
}
public virtual HashSet<Session> Sessions { get; set; }

Is it possible? If so, how?

EF code generator creates entity classes as partial , so you may create another code file in the same assembly with some tricks:

public partial class Conference
{
    [XmlIgnore]
    public bool SessionsSpecified
    {
        get { return false; }
    }

    public Session[] SerializableSessions
    {
        get { return new Sessions.ToArray(); }
        set { Sessions = value; }
    }
}

SessionSpecified property is a XmlSerializer trick to ignore Sessions property during serialization. Session[] will be serialized instead of ICollection. Check if it is possible to expose internal EF collection types to use cast instead of copying an array.

Alternative solution is to implement IXmlSerializable and have a full control of how Conference class serialized.

I used T4 template .

In the template, I changed ICollection to List , and added [Serializable] to entity types and complex types.

I also had to disable proxy type generation:

((IObjectContextAdapter)entities).ObjectContext.ContextOptions.ProxyCreationEnabled = false;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM