简体   繁体   English

我可以让实体框架使用具体类而不是接口(用于Web服务序列化)

[英]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). 我正在学习Web服务,我正在使用的书是使用实体框架从SQL服务器中提取数据(我对此也知之甚少)。

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. 无法序列化System.Collections.Generic.ICollection类型的成员X ...因为它是一个接口。

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): 理想情况下,我可以告诉实体框架生成这样的东西(甚至更好,控制具体类型,以便我可以告诉实体框架如果我想要使用List):

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: EF代码生成器将实体类创建为部分类,因此您可以使用一些技巧在同一程序集中创建另一个代码文件:

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. SessionSpecified属性是在序列化期间忽略Sessions属性的XmlSerializer 技巧 Session[] will be serialized instead of ICollection. Session []将被序列化而不是ICollection。 Check if it is possible to expose internal EF collection types to use cast instead of copying an array. 检查是否可以公开内部EF集合类型以使用强制转换而不是复制数组。

Alternative solution is to implement IXmlSerializable and have a full control of how Conference class serialized. 替代解决方案是实现IXmlSerializable并完全控制Conference类的序列化方式。

I used T4 template . 我用过T4模板

In the template, I changed ICollection to List , and added [Serializable] to entity types and complex types. 在模板中,我将ICollection更改为List ,并将[Serializable]添加到实体类型和复杂类型。

I also had to disable proxy type generation: 我还必须禁用代理类型生成:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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