WCF与实体框架代码第一关系

时间:2011-10-25 21:13:50

标签: wcf entity-framework

我正在学习WCF,并尝试创建一个公开Project及其任务的小型服务(标准的Entity Framework hello world)。

类结构如下:

public class Project
{
    public int ProjectId { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public DateTime CreationDate { get; set; }
    public virtual ICollection<Task> Tasks { get; set; }
}

public class Task
{
    public int TaskId { get; set; }
    public string Title { get; set; }
    public virtual Project RelatedProject { get; set; }
}

DB上下文出现在:

之后
public class ProjectContext : DbContext
{
    public DbSet<Project> Projects { get; set; }
    public DbSet<Task> Tasks { get; set; }
}

最后,服务端点:

    public IEnumerable<Project> getProjects()
    {
        ProjectContext p = new ProjectContext();
        return p.Projects.AsEnumerable();
    }

问题是这个模型会抛出一个System.ServiceModel.CommunicationException,但是,如果我从模型中删除虚拟属性,它会工作,但我会松开Project和Task之间的实体框架链接。

有类似设置的人吗?

2 个答案:

答案 0 :(得分:2)

我用这个把头撞了几个小时。经过大量调试后,谷歌给出了答案,我觉得在这里发布是正确的,因为这是我在谷歌获得的第一个结果。

[ServiceContract]接口声明(通常为IProjectService.cs

)之上添加此类
public class ApplyDataContractResolverAttribute : Attribute, IOperationBehavior
{
    public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
    {

    }

    public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
    {
        var dataContractSerializerOperationBehavior =
            description.Behaviors.Find<DataContractSerializerOperationBehavior>();
        dataContractSerializerOperationBehavior.DataContractResolver =
            new ProxyDataContractResolver();
    }

    public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
    {
        var dataContractSerializerOperationBehavior =
            description.Behaviors.Find<DataContractSerializerOperationBehavior>();
        dataContractSerializerOperationBehavior.DataContractResolver =
            new ProxyDataContractResolver();
    }

    public void Validate(OperationDescription description)
    {
        // Do validation.
    }
}

要求是

using System.ServiceModel.Description;
using System.Data.Objects;
using System.ServiceModel.Channels;

然后在[OperationContract]关键字下添加[ApplyDataContractResolver]关键字,您就可以了!

非常感谢http://blog.rsuter.com/?p=286

答案 1 :(得分:0)

要通过WCF发送数据,您应该禁用延迟加载(dataContext.ContextOptions.LazyLoadingEnabled = false;)。

为了确保加载了您想要的数据,您需要使用预先加载(通过Include方法)。

您需要将功能更改为:

 public IEnumerable<Project> getProjects()
    {
        ProjectContext p = new ProjectContext();
        p.ContextOptions.LazyLoadingEnabled = false;

        return p.Projects.Include("Tasks").AsEnumerable();
    }