WCF с Entity Framework Code First отношения - PullRequest
1 голос
/ 26 октября 2011

Я изучаю WCF и попытался создать небольшой сервис, который представляет проект и его задачи (стандартный привет-мир Entity Framework).

Структура класса следующая:

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; }
}

Контекст БД появляется после:

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 ]

2 голосов
/ 05 февраля 2013

Я несколько часов ударился головой о стену с этим.После обширной отладки Google дал ответ, и я чувствую, что правильно разместить его здесь, так как это был первый результат, который я получил в Google.

Добавьте этот класс поверх вашей [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

0 голосов
/ 26 октября 2011

Для отправки данных через WCF следует отключить отложенную загрузку (dataContext.ContextOptions.LazyLoadingEnabled = false;).

Чтобы убедиться, что нужные данные загружены, вам необходимо использовать активную загрузку (через метод Include).

Вам нужно изменить свою функцию на:

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

        return p.Projects.Include("Tasks").AsEnumerable();
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...